哈夫曼树&哈夫曼编码
哈夫曼树(最优二叉树)
-
具有最小带权路径长度的二叉树称为哈夫曼树
-
权值越大的叶子节点越靠近根节点
-
权值越小的叶子节点越远离根节点
-
总是将最小权值和次最小权值的两个节点合并,依次往上构造树,这样根节点的权值就是最小权值
-
假如哈夫曼树有n0个叶子节点,那么这棵树的总结点个数n=2*n0-1
typedef struct{
int weight;
int parent;
int lchild;
int rchild;
}HNode;
void Create_HuffMTree(HNode HFMTree[],int n){
//n为叶子结点个数
int x1,x2; //x1和x2存储最小和次最小权值
int m1,m2; //m1和m2存储位置
int i,j;
for(i=0;i<2*n-1;++i){
//HFMTree 初始化
HFMTree[i].weight=0;
HFMTree[i].lchild=-1;
HFMTree[i].rchild=-1;
HFMTree[i].parent=-1;
}
for(i=0;i<n;++i)
cin>>HFMTree[i].weight; //输入n个叶子节点的权值
for(i=0;i<n-1;++i){
x1=x2=INT_MAX;
m1=m2=0;
for(j=0;j<n+i;++j){
if(HFMTree[i].parent==-1&&HFMTree[j].weight<x1){
x2=x1;
m2=m1;
x1=HFMTree[j].weight;
m1=j;
}
else if(HFMTree[i].parent==-1&&HFMTree[j].weight<x2){
x2=HFMTree[j].weight;
m2=j;
}
}
HFMTree[m1].parent=n+i;HFMTree[m2].parent=n+i; //合并
HFMTree[n+i].weight=HFMTree[m1].weight+HFMTree[m2].weight;
HFMTree[n+i].lchild=m1;HFMTree[n+i].rchild=m2;
}
}
哈夫曼编码(前缀编码)
- 规定哈夫曼树中的左分支代表0,右分支代表1,从根节点到每个叶子节点所经过的路径分支组成的0和1的序列便为该节点对应字符的编码
const int n=10; //叶子节点个数
typedef struct{
int bit[n];
int start;
}HCode;
HNode HFMTree[10]; //设已经建立好的哈夫曼树已经存在HFMTree中
void HuffmanCode(HNode HFMTree[],HCode HuffCode[]){
HCode cd;
int i,j,c,p;
for(i=0;i<n;++i){
cd.start=n-1;
c=i;
p=HFMTree[c].parent;
while(p!=-1){
if(HFMTree[p].lchild==c)
cd.bit[cd.start]=0;
else
cd.bit[cd.start]=1;
cd.start--;
c=p;
p=HFMTree[c].parent;
}
for(j=cd.start+1;j<n;++j)
HuffCode[i].bit[j]=cd.bit[j];
HuffCode[i].start=cd.start+1;
}
}