霍夫曼编码(又名哈夫曼编码)

        哈夫曼编码(Huffman Coding)是一种编码方式,哈夫曼编码是可变字长编码(VLC)的一种。Huffman于1952年提出一种编码方法,该方法完全依据字符出现概率来构造异字头的平均长度最短的码字,有时称之为最佳编码,一般就叫作Huffman编码(有时也称为霍夫曼编码)。

       霍夫曼编码即是一种最优二叉树的实现。我们为什么要采用编码呢?计算机中的信息都是以二进制存储的,如字符编码的ASCII码,BCD码等等。然而大量的二进制的存储会造成空间的浪费,我们知道有些数据含有的0或1比较多,多余的信息我们就可以把它去除,所以出现了很多的压缩算法。常见的有LZW、DEFLAT、LZ等等(多谢 ruki 指出错误之处,LZ系列的压缩率的确比霍夫曼编码高)。然而为什么不用霍夫曼编码呢?从理论上说霍夫曼编码的效率是最高的,但是其执行效率却比较差,也就是说数据压缩所需要的时间比较长,我们总不会希望压缩1G的文件却使用半小时吧。所以前面提到的那些算法在速度上比霍夫曼编码快而已,数据压缩率却没有霍夫曼编码的高。那为什么我们还要了解霍夫曼编码呢?

        其实霍夫曼编码虽然在数据压缩领域使用的较少,但是在通信领域却得到广泛的应用。霍夫曼编码的基本原理即是从底向上生成二叉树,如果出现多个二叉树则将其合并。例如:

有一组数据,3 4 7 8 9 12 16

天蓝色的数字是原始数据,红色数字是其下方两个数字之和

第一步:

     

3        

第二步:

                14 

        7                7

           


第三步:

                14

        7                7                                    17

            4                                                   9 


第四步:

                14

                      7                         17                           28

                                         8           9               12          16

第五步: 将子树合并

                                                              59

                                            31                           28                      

                                  14              17           12            16

                             7         7      8          9  

                       3        4  


代码如下

#include <stdio.h>
#define MAX_WEIGHT 10000
#define MAX_LEAF 30
#define MAX_NODE MAX_LEAF*2-1
#define MAX_BIT 12
typedef int data_t;
typedef struct huff_node {
        int weight;
        int parent;
        int lchild;
        int rchild;
} huff_t;
typedef struct huff_code {
        int bit[MAX_BIT];
        int start;
} huff_code_t;
void huffman_tree(huff_t huff_tree[], int num, data_t weight[])
{
        int i, j, m1, m2, x1, x2, n = num;
        for (i = 0; i < 2 * n - 1; i++) {
                huff_tree[i].weight = 0;
                huff_tree[i].parent = -1;
                huff_tree[i].lchild = -1;
                huff_tree[i].rchild = -1;
        }
        for (i = 0; i < n; i++) {
                huff_tree[i].weight = weight[i];
        }
        for (i = 0; i < n - 1; i++) {
                m1 = m2 = MAX_WEIGHT;
                x1 = x2 = 0;
                for (j = 0; j < n + i; j++) {
                        if (huff_tree[j].weight < m1
                                        && huff_tree[j].parent == -1) {
                                m2 = m1;
                                x2 = x1;
                                m1 = huff_tree[j].weight;
                                x1 = j;
                        } else if (huff_tree[j].weight < m2
                                        && huff_tree[j].parent == -1) {
                                m2 = huff_tree[j].weight;
                                x2 = j;
                        }
                }
                huff_tree[x1].parent = n + i;
                huff_tree[x2].parent = n + i;
                huff_tree[n + i].weight = huff_tree[x1].weight
                                + huff_tree[x2].weight;
                huff_tree[n + i].lchild = x1;
                huff_tree[n + i].rchild = x2;
        }
}
void huffman_code(huff_t arry[], int num)
{
        int i, j, c, p;
        huff_code_t cd, huff_code[MAX_NODE];
        for (i = 0; i < num; i++) {
                cd.start = num - 1;
                c = i;
                p = arry[c].parent;
                while (p != -1) {
                        if (arry[p].lchild == c)
                                cd.bit[cd.start] = 0;
                        else
                                cd.bit[cd.start] = 1;
                        cd.start--;
                        c = p;
                        p = arry[c].parent;
                }
                for (j = cd.start + 1; j < num; j++)
                        huff_code[i].bit[j] = cd.bit[j];
                huff_code[i].start = cd.start;
        }
        for (i = 0; i < num; i++) {
                for (j = huff_code[i].start + 1; j < num; j++)
                        printf("%d\t", huff_code[i].bit[j]);
                printf("\n");
        }

}
int main()
{
        const int length = 7;
        data_t weight[7] = { 3,4,7,8,9,12,16 };
        huff_t arry[MAX_NODE];
        huffman_tree(arry, length, weight);
        huffman_code(arry, length);
        printf("\n");
        return 0;
}

今天就到这,下次接着写。:)


你可能感兴趣的:(霍夫曼编码,最优二叉树)