ハフマンツリー&ハフマンコード
ハフマンツリー(最適なバイナリツリー)
-
加重パス長が最小のバイナリツリーは、ハフマンツリーと呼ばれます。
-
重みが大きいリーフノードはルートノードに近くなります
-
重みが小さいほど、リーフノードはルートノードから遠くなります。
-
ルートノードの重みが最小の重みになるように、常に最小の重みと次に小さい重みを持つ2つのノードをマージし、順番にツリーを構築します。
-
ハフマンツリーに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;
}
}