哈夫曼树及其编码

Posted lsy-lsy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了哈夫曼树及其编码相关的知识,希望对你有一定的参考价值。

首先是哈夫曼树的定义:在一棵二叉树中,带权路径长度达到最小,成这样的树是最优二叉树,也是哈弗曼树。大概意思就是把数值大的节点放在树上面,数值小的节点放在树下面。哈夫曼树的结构使用顺序结构,这里直接使用了数组。

建造哈弗曼树的思路:根据二叉树的性质,有n个叶子节点,二叉树就会有2n-1个节点。定义一个数组,前n个节点作为叶子节点,从前n个节点中选择两个最小的节点,作为一棵二叉树的左右节点,这棵二叉树的根节点值为左右孩子节点值之和。把这个根节点的值放入数组中,然后接着从数组中(新加入的节点也算)选取两个最小的节点,只不过把已经使用过的节点忽略掉,这样不断循环,每个节点和其他节点都有对应关系。

技术图片

代码实现:

定义结构体,里面有四个成员,分别为权值,父节点,左孩子节点,右孩子节点,这里的节点指的是他在数组中对应的下标位置,如果是0则没有父节点或者孩子节点,权值不能为0.

 

 1 #include<stdio.h>
 2 #include<stdlib.h>
 3 #include<string.h>
 4 #define n 7
 5 #define m 2*n-1
 6 #define maxval 100
 7 
 8 typedef struct{
 9     int weight;
10     int parent,lchild,rchild;
11 }HufmTree;
12 
13 HufmTree *init(){
14     
15     HufmTree *hf = (HufmTree *)malloc(sizeof(HufmTree));
16     if(hf==NULL)
17         return NULL;
18     
19     return hf;
20     
21 }
22 
23 void setHuffmanTree(HufmTree *tree[]){
24     
25     int i,j,p1,p2,s1,s2;
26     for(i=n;i<m;i++){                        //从n位置开始,都是两个节点新合成的节点,直到m位置结束 
27         p1 = p2 = 0;                         //每次循环开始,都要数组从头开始遍历 
28         s1 = s2 = maxval;                    
29         for(j=0;j<=i-1;j++)                    //在所有节点中寻找,i后面没有数值的空位置用不到 
30             if(tree[j]->parent==0)             //此处的代码的作用是检查该节点是否已经使用过,因为使用过的节点肯定有父节点    
31                 if(tree[j]->weight<s1){        //寻找最小权值的节点 
32                     s2 = s1;                    
33                     s1 = tree[j]->weight;
34                     p2 = p1;
35                     p1 = j;
36                 }
37                 else if(tree[j]->weight<s2){//寻找次小权值的节点 
38                     s2 = tree[j]->weight;
39                     p2 = j;
40                 }
41         tree[p1]->parent = tree[p2]->parent = i;    //把两个最小节点的父节点指向i 
42         tree[i]->weight = tree[p1]->weight + tree[p2]->weight;    //父节点权值等于左右孩子权值之和 
43         tree[i]->lchild = p1;                //指明父节点的左右孩子节点 
44         tree[i]->rchild = p2;
45     }
46     
47 }
48 
49 void display(HufmTree *tree[n]){
50     
51     int i;
52     for(i=0;i<m;i++){
53         printf("%d ",tree[i]->weight);
54     }
55     printf("
");
56 }

 

哈弗曼编码:使出现频率高的编码放在上面,频率低的编码放在下面。

 技术图片

 

以上图为例,其中A的频率最高,离根节点最近,GFED频率最低,在最下面。

实现原理:从根节点到每个叶子节点间的路径值作为编码,图片里的规定是左子树的路径为1,右子树的路径为0,这样每个节点都有自己的编码且不会重复

 1 void createHuffmanCode(HufmTree *tree[n]){
 2      
 3      
 4      int i,j,p,start;
 5      char *temp;                                    //临时存放字母编码的数组 
 6      for(i=0;i<n;i++){                            //从0~n之间都是二叉树的叶子节点 
 7          start = n-1;                            //存放temp数组的下标,从后往前,指向最后面 
 8          temp = (char *)malloc(n*sizeof(char));    //为数组分配空间 
 9         temp[start] = ;                        //添加字符串结束标志 
10          j = i;                                    //j代表为哪个叶子节点编码 
11         p = tree[j]->parent;                    //p是j的父节点 
12          while(p!=0){
13              if(tree[p]->lchild==j)
14                  temp[--start] = 0;            //如果j是p的左孩子,则在数组中添加一个 ‘0‘
15             else
16                 temp[--start] = 1;            //反之则添加一个 ‘1‘
17             j = p;
18             p = tree[p]->parent;                //j和p不断往上循环 
19         }
20         printf("%d:%s 
",tree[i]->weight,&temp[start]);
21     }
22      
23  }
24  
25 void main(){
26     
27     HufmTree *tree[m];
28     int i,num[n] = {7,3,2,4,9,10,5};
29     
30     //分配空间 
31     for(i=0;i<m;i++)
32         tree[i] = init();
33         
34     //数组每个节点内的所有值初始化时都设为0 
35     for(i=0;i<m;i++){
36         tree[i]->weight = 0;
37         tree[i]->parent = 0;
38         tree[i]->rchild = 0;
39         tree[i]->lchild = 0;
40     }
41     
42     //为数组前n个数的权值赋值 
43     for(i=0;i<n;i++)
44         tree[i]->weight = num[i];
45     
46     setHuffmanTree(tree);
47     
48     display(tree);
49     
50     createHuffmanCode(tree);
51     
52 }

 

 

 

 

 

 

 

 

 

 

 

 

 

 

以上是关于哈夫曼树及其编码的主要内容,如果未能解决你的问题,请参考以下文章

数据结构树与树的表示二叉树存储结构及其遍历二叉搜索树平衡二叉树堆哈夫曼树与哈夫曼编码集合及其运算

百度看到您的 请问 那个哈夫曼树和哈夫曼编码。。。跪谢!

哈夫曼树定义及其构造和编码(C语言)

数据结构===哈夫曼编码实现/C或者C++

构造哈夫曼树的过程

霍夫曼编码