Huffman

2022-11-15
一、目的 Objective
1. 掌握霍夫曼树的生成
2. 掌握霍夫曼编码
二、内容 Contents
1. 以表格的形式构造霍夫曼树{2, 3, 6, 7}
2. 编写程序构造霍夫曼树{2, 3, 6, 7}并根据表格验证程序的正确性
3. 使用{9, 11, 5, 7, 8, 2, 3}再次完成霍夫曼树的生成和编码
三、参考代码 Source
1. 头文件Huffman.h
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define INIT -1
typedef struct Node
{
    int w;
    int left;
    int right;
    int parent;
} Node, HTree;

void sel(HTree htree[], int curInd, int *min1, int *min2)
{
    int i;
    *min1 = *min2 = INIT;
    for (i = 0; i < curInd; i++)
    {
        // ignore those nodes with parents
        if (htree[i].parent != INIT)
        {
            continue;
        }
        // init min1 and min2
        if (*min1 == INIT)
        {
            *min1 = *min2 = i;
        }
        else
        {
            if (htree[i].w <= htree[*min1].w)
            {
                *min2 = *min1;
                *min1 = i;
            }
            else if (htree[i].w < htree[*min2].w)
            {
                *min2 = i;
            }
            else if (htree[i].w > htree[*min2].w)
            {
                if (*min1 == *min2)
                {
                    *min2 = i;
                }
            }
        }
    }
}

void display(HTree htree[], int n)
{
    int i;
    for (i = 0; i < n; i++)
    {
        printf("i=%d\tw=%d\tparent=%d\tleft=%d\tright=%d\t\n", i, htree[i].w, htree[i].parent, htree[i].left, htree[i].right);
    }
}

void createTree(HTree htree[], int w[], int n)
{
    int i;
    for (i = 0; i < 2 * n - 1; i++)
    {
        htree[i].parent = INIT;
        htree[i].left = INIT;
        htree[i].right = INIT;
    }
    for (i = 0; i < n; i++)
    {
        htree[i].w = w[i];
    }
    // create
    for (i = n; i < 2 * n - 1; i++)
    {
        int min1, min2;
        sel(htree, i, &min1, &min2);
        htree[i].w = htree[min1].w + htree[min2].w;
        htree[i].left = min1;
        htree[i].right = min2;
        htree[min1].parent = htree[min2].parent = i;
    }
}

void encode(HTree htree[], char *hcode[], int n)
{
    int i, start, cur, p;
    // temp array
    char temp[n];
    temp[n - 1] = '\0';

    for (i = 0; i < n; i++)
    {
        start = n - 1;
        cur = i;
        p = htree[i].parent;
        while (p != INIT)
        {
            start--;
            if (htree[p].left == cur)
            {
                temp[start] = '0';
            }
            else
            {
                temp[start] = '1';
            }
            cur = p;
            p = htree[p].parent;
        }
        // copy the code to hc[i] with size n-start
        hcode[i] = (char *)malloc(sizeof(char) * (n - start));
        strcpy(hcode[i], &temp[start]);
        printf("inside: i=%d\thcode[%d]=%s\n", i, i, hcode[i]);
    }
}

void displayCode(char *hcode[], int w[], int n)
{
    int i;
    for (i = 0; i < n; i++)
    {
        printf("i=%d\tw[%d]=%d\thcode=%s\n", i, i, w[i], hcode[i]);
    }
}
2. 主文件Huffman.c
#include "Huffman.h"

void main(void)
{
    int i;
    int n = 7;
    // int w[] = {2, 4, 5, 3};
    int w[] = {9, 11, 5, 7, 8, 2, 3};
    HTree htree[2 * n - 1];
    char *hcode[n];

    createTree(htree, w, n);
    display(htree, 2 * n - 1);
    encode(htree, hcode, n);
    displayCode(hcode, w, n);
}
源码来源: 懒猫老师
要求 Requirement
1. 利用 线上环境 或线下环境,独立完成
2. 写出实验的具体流程和实验的结果,相应的地方需要截图说明
3. 程序调试运行中出现的错误信息原因分析
4. 完成 实验报告 并提交到 学习通;详见作业要求