<span style="font-size:18px;">/* 1.在一棵二叉树中,我们定义从A节点到B节点所经过的分支序列为从A节点到B节点的路径; 定义从A节点到B节点所经过的分支个数为从A节点到B节点的路径长度。 定义从二叉树的根节点到二叉树中全部叶节点的路径长度之和为该二叉树的路径长度。 2.假设二叉树中的叶节点都带有权值,则能够把这个定义推广。设二叉树有n歌带权值的叶节点,定义从二叉树的 根节点到二叉树中全部叶节点的路径长度与相应叶节点权值的乘积之和为该二叉树的带权路径长度。 WPL=(wi*li)(i从1到n) 3.我们把具有最小带权路径长度的二叉树称作哈夫曼树或最优二叉树 4.哈夫曼树构造算法: (1):由给定的n个权值{w1,w2,w3,...,wn}构造n棵仅仅有根节点的二叉树,从而得到一个二叉树森林F={T1,T2,T3,....,TN}。 (2):在二叉树森林F中选取根节点的权值最小和次小的两棵二叉树作为新的二叉树的左右子树构造新的二叉树, 新的二叉手的根节点权值为左右子树根节点权值之和。 (3):从二叉树森林F中删除作为新二叉树左右子树的两棵二叉树,将新二叉树增加到二叉树森林F中。 (4):反复步骤(2)(3)。当二叉树森林F中仅仅剩下一颗二叉树时。这棵二叉树就是所构造的哈夫曼树 5.哈夫曼树能够用于解决最优化问题。比如电文的编码问题 */ #include<stdio.h> #include<malloc.h> #include<stdlib.h> #define MaxN 10//初始设定的最大结点个数 #define MaxValue 10000//初始设定的权值最大值 #define MaxBit 4//初始设定的最大编码位数 typedef struct{ int weight;//权值 int flag;//标记,是否已经增加到哈夫曼树中 int parent;//双亲节点下标 int leftChild;//左孩子下标 int rightChile;//右孩子下标 }HaffNode;//哈夫曼树的结点构体 typedef struct{ int bit[MaxN];//数组 int start;//编码的起始下标 int weight;//字符的权值 }Code;//哈夫曼编码的结构 //建立哈夫曼树 void Haffman(int weight[],int n,HaffNode haffTree[]){ //建立叶结点个数为n,权值数组为weight的哈夫曼树haffTree int i,j,m1,m2,x1,x2; //哈夫曼树的haffTree的初始化,n个叶节点的二叉树共同拥有2n-1个结点 for(i=0;i<2*n-1;i++){ if(i<n){ haffTree[i].weight=weight[i]; }else{ haffTree[i].weight=0; } haffTree[i].parent=-1; haffTree[i].flag=0; haffTree[i].leftChild=-1; haffTree[i].rightChile=-1; } //构造哈夫曼树haffTree的n-1个非叶节点 for(i=0;i<n-1;i++){ m1=m2=MaxValue; x1=x2; for(j=0;j<n+i;j++){//找出权值最小和次小的子树 if(haffTree[j].weight<m1&&haffTree[j].flag==0){ //x1最小的下标,x2次小的下标,m1最小的权值,m2次小的权值 //flag==0表示还没有增加到哈夫曼树 m2=m1; x2=x1; m1=haffTree[j].weight; x1=j; }else if(haffTree[j].weight<m2&&haffTree[j].flag==0){ m2=haffTree[j].weight; x2=j; } } //将找出的两棵权值最小和次小的子树合并为一棵 haffTree[x1].parent=n+i; haffTree[x2].parent=n+i; haffTree[x1].flag=1; haffTree[x2].flag=1; haffTree[n+i].weight=haffTree[x1].weight+haffTree[x2].weight; haffTree[n+i].leftChild=x1; haffTree[n+i].rightChile=x2; } } void HaffmanCode(HaffNode haffTree[],int n,Code haffCode[]){ //由n个结点的哈夫曼树haffTree构造哈夫曼编码haffCode Code *cd=(Code *)malloc(sizeof(Code)); int i,j,child,parent; //求n个叶结点的哈夫曼编码 for(i=0;i<n;i++){ cd->start=n-1;//不等长编码的最后一位为n-1 cd->weight=haffTree[i].weight;//取得编码相应的权值 child=i; parent=haffTree[child].parent; //由叶节点向上直到根结点 while(parent!=-1){ if(haffTree[parent].leftChild==child){ cd->bit[cd->start]=0;//左孩子分支编码0 }else{ cd->bit[cd->start]=1;//右孩子分支编码1 } cd->start--; child=parent; parent=haffTree[child].parent; } for(j=cd->start+1;j<n;j++){ haffCode[i].bit[j]=cd->bit[j];//保存每一个叶节点的编码 } haffCode[i].start=cd->start+1;//保存叶结点编码的起始位 haffCode[i].weight=cd->weight;//保存编码相应的权值 } } void main(){ int i,j,n=4; int weight[]={1,3,5,7}; HaffNode *myHaffTree=(HaffNode *)malloc(sizeof(HaffNode)*(2*n-1)); Code *myHaffCode=(Code *)malloc(sizeof(Code)*n); if(n>MaxN){ printf("给出的n越界。改动MaxN!!!\n"); exit(1); } Haffman(weight,n,myHaffTree); HaffmanCode(myHaffTree,n,myHaffCode); //输出每一个叶节点的哈夫曼编码 for(i=0;i<n;i++){ printf("Weight=%d Code=",myHaffCode[i].weight); for(j=myHaffCode[i].start;j<n;j++){ printf("%d",myHaffCode[i].bit[j]); } printf("\n"); } }
haffman哈夫曼编码的实现
转载本文章为转载内容,我们尊重原作者对文章享有的著作权。如有内容错误或侵权问题,欢迎原作者联系我们进行内容更正或删除文章。
上一篇:南京IT企业环境之最深心得体会
提问和评论都可以,用心的回复会被更多人看到
评论
发布评论
相关文章
-
哈夫曼编码ii
-
java 哈夫曼编码算法 哈夫曼编码编程实现
给定一篇用于通信的英文电文,统计该电文中每个字符出现的频率,按频率左小右大的方法为这些字符建立哈夫曼(Huffamn)树,并编出每个字符的哈夫曼树码,输出该电文的哈夫曼码译文。
java 哈夫曼编码算法 数组 i++ #include