ハフマンツリー構造
- デザインハフマンツリーノード構造、我々は、デコーダにルートノードから親、lchild、rchild、重量を備えたノード構造をリーフノードとリーフノードへのルートからコーディングを解決する必要があるため。
- 我々は、点のハフマン木の概要を知ってN = 2 * N-1、構造体のアレイは、ハフマンツリーのすべてのノードを格納するために使用することができる場合、アレイのサイズはN、添字[0、N-1]でありますリーフノード情報は、(N四角)格納され、[N、N-1]の組合せ情報(N-1乗)を格納するノードの。何として示されていないすべての親ノード、lchild、rchild = -1を、初期化します。割り当て重みは正しい値、または他の割り当てを持っている-1。
- 常にアレイ内の最小重量二つのノードを探して、二分木のこれらの二つのルートノードの順序は、生成配列[N、N-1]に加え、その親、lchild、rchild、重みを更新しています。完全な配列、ハフマン木の形まで。
- PS:次の番号は、以下にそれらのいずれかよりも左の二つの数字である場合には、選択機能の考え方を達成することが注目され、ユーザーが使用したコードを学ぶ、シンプル、s1とs2の配列の2つの既存のフロントです次いで、小さい方、及びアレイが最小と二番目に小さい番号を残し、完了するまで数を残しました。(また最小とバブルソートの二番目に小さい重みを選択)
#include <iostream>
#include <cstdio>
#include <cstdlib>
using namespace std;
/*哈夫曼树的应用----哈夫曼编码*/
/*
根据哈夫曼算法:
1.若给定n个权值的结点构造n棵二叉树, 其中n棵二叉树的根结点分别为这n个结点,
且其没有左右子树,则这n棵二叉树构成的集合记为为集合F ={T1,T2,T3...Tn}
2.将集合F中根结点权值之和最小的两棵二叉树作为一个新增结点的左右子树,新增结点的权
值为这两棵二叉树的权值和,将该新增结点构造的二叉树加入集合F中,并从F中删除这两棵树。
3.重复步骤2直到集合F中只含有一棵树为止。(此时该树即为所求哈夫曼树)
*/
//哈夫曼树的结点结构
typedef struct HuffmanTree{
int weight;
int parent,lchild,rchild; //编码及译码需要这三个信息
}HTNode,*HTree;
typedef char** HuffmanCode;
void HuffmanCoding(HTree& HT,HuffmanCode& HC,int *w,int n);
void select(HTree HT,int t,int&s1,int&s2);
void HuffmanCoding(HTree& HT,HuffmanCode& HC,int *w,int n)
{
int s1,s2;
int m;
int i=0;
if(n<=1) return;
m=2*n-1; //哈夫曼树的结点个数
HT=(HTNode*)malloc(sizeof(HTNode)*(m));
HTree p=HT;
for(i=0;i<n;++i,++p,++w)
{
//-1表示不存在
*(p)={*w,-1,-1,-1}; //初始化叶子结点完成
}
for(;i<m;++i,++p)
{
*(p)={-1,-1,-1,-1}; //除叶子结点外的结点初始化完成
}
cout<<"初始化后:"<<endl;
cout<<"双亲"<<'\t'<<"左孩子"<<'\t'<<"右孩子"<<'\t'<<"权值"<<endl;
for(int i=0;i<7;i++)
{
cout<<HT[i].parent<<'\t'<<HT[i].lchild<<'\t'<<HT[i].rchild<<'\t'<<HT[i].weight<<endl;
}
for(i=n;i<m;++i)
{
//在HT[0..n]中选择parent为0且weight最小的两个结点,其序号分别为s1和s2
select(HT,i,s1,s2);
HT[s1].parent=i;
HT[s2].parent=i;
HT[i].lchild=s1;
HT[i].rchild=s2;
HT[i].weight=HT[s1].weight+HT[s2].weight;
}
}
void select(HTree HT,int t,int&s1,int&s2)
{
//在HT[0..n]中选择parent为0且weight最小的两个结点,其序号分别为s1和s2
int i,m,n;
m=n=10000;
for(i=0;i<t;i++)
{
if(HT[i].parent==-1&&(HT[i].weight<m||HT[i].weight<n))
{
if(m<n)
{
n=HT[i].weight;
s2=i;
}
else
{
m=HT[i].weight;
s1=i;
}
}
}
if(s1>s2) //s1放较小的序号
{
i=s1;
s1=s2;
s2=i;
}
}
int main()
{
int w[4]={7,5,2,4};
HTree HT;
HuffmanCode HC;
HuffmanCoding(HT,HC,w,4);
cout<<'\n'<<"完成后:"<<endl;
cout<<"双亲"<<'\t'<<"左孩子"<<'\t'<<"右孩子"<<'\t'<<"权值"<<endl;
for(int i=0;i<7;i++)
{
cout<<HT[i].parent<<'\t'<<HT[i].lchild<<'\t'<<HT[i].rchild<<'\t'<<HT[i].weight<<endl;
}
return 0;
}
結果: