树-哈夫曼编码
Posted mlblog27
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了树-哈夫曼编码相关的知识,希望对你有一定的参考价值。
哈夫曼树(最优二叉树)
每个叶子节点都有权值,权值越大的叶节点越靠近根节点,而权值越小的叶节点越远离根节点
建立规则:
依据给出的n个权值,选择最小的两个权值作为一棵新的二叉树的左右子树,并且新的根节点的权值为左右子树权值之和
将新根节点与剩下的有权值的节点重复此操作直至只剩一个根节点
哈夫曼编码:
在哈夫曼树的基础上,规定哈夫曼树中的左分支代表0,右分支代表1,从根节点到每个叶节点所经过的路径分支组成的0和1的序列便是该节点对应字符的编码
源码:
亲测有效
//哈夫曼树及哈夫曼编码 #include<stdio.h> #include<malloc.h> #define MAXLEN 100 typedef struct node{ int weight; //整型权值变量 int lchild,rchild,parent; //左孩子,右孩子,双亲 }HFNode; typedef HFNode HFMT[MAXLEN]; int n; int InitHFMT(HFMT T) //初始化 { int i; printf(" 请输入共有多少个权值(小于100):"); //叶子节点数 scanf("%d",&n); for(i = 0;i < 2*n-1;i++) { T[i].weight = 0; T[i].lchild = -1; T[i].rchild = -1; T[i].parent = -1; } return 0; } int InputWeight(HFMT T) //输入权值 { int w,i; for(i = 0;i < n;i++) { printf(" 请输入第%d个叶子节点的权值:",i+1); scanf("%d",&w); T[i].weight = w; } return 0; } int SelectMin(HFMT T,int i,int *p1,int *p2) //选择两个节点中小的节点 { long min1 = 999999; //预设两个值,使它大于可能出现的最大权值 long min2 = 999999; int j; for(j = 0;j <= i;j++) { if(T[j].parent == -1) { if(T[j].weight < min1) { min1 = T[j].weight; //找出最小的权值,通过*p1带回权值 *p1 = j; } } } for(j = 0;j <=i;j++) { if(T[j].parent == -1) { if(T[j].weight < min2 && j != (*p1)) { min2 = T[j].weight; //找出次最小的权值,通过*p2带回序号 *p2 = j; } } } return 0; } int CreatHFMT(HFMT T) //构建哈夫曼树,T(2*n-1)为根节点 { int i,p1,p2; InitHFMT(T); InputWeight(T); for(i = n;i < 2*n-1;i++) { SelectMin(T,i-1,&p1,&p2); T[p1].parent = T[p2].parent = i; T[i].lchild = p1; T[i].rchild = p2; T[i].weight = T[p1].weight + T[p2].weight; } return 0; } int PrintHFMT(HFMT T) //输出向量状态表 ,打印哈夫曼树 { printf(" 哈夫曼树的各边显示:"); int i=0,k=0; for(i = 0;i < 2*n-1;i++) { if(T[i].lchild != -1) { if( !(k%2) ) printf(" "); printf(" (%d,%d),(%d,%d)",T[i].weight,T[ T[i].lchild ].weight,T[i].weight,T[ T[i].rchild ].weight); k++; } printf(" "); } return 0; } int hfnode(HFMT T,int i) { int j; j = T[i].parent; if(j != -1) { if(T[j].lchild == i) printf("0"); else printf("1"); i = j; hfnode(T,i); } return 0; } int huffmannode(HFMT T) //求哈夫曼编码 { printf(" 输入的权值对应的逆置的哈夫曼编码(从叶节点到根节点):"); int i,a,k = 0; for(i = 0;i < n;i++) { a = i; if(!(k%2)) printf(" "); printf(" %d:",T[i].weight); k++; hfnode(T,i); i = a; } return 0; } int main() { HFMT HT; CreatHFMT(HT); PrintHFMT(HT); huffmannode(HT); printf(" "); return 0; }
以上是关于树-哈夫曼编码的主要内容,如果未能解决你的问题,请参考以下文章