哈夫曼编码的基本思想时以字符的使用频率作为权构建一颗哈夫曼树,然后利用哈夫曼树对字符进行编码。构造一颗哈夫曼树,是将所有的编码的字符作为叶子结点,该字符在文件中的使用频率作为叶子结点的权值,以自底向上的方式,通过n-1次的”合并“运算后构造处一颗树,
核心思想是权值越大的叶子离根越近。
哈夫曼算法的贪心策略是每次从树的集合中取出没有双亲权值最小的两棵树作为左右子树,构造一颗新树新树根节点的权值为其左右孩子结点权值之和,将新树插入到树的集合中
#include<iostream>
using namespace std;
#define Max 10000
const int maxn=1000+5;
int n;
struct h_Tree{
double weight;//权重
int lchild;//左儿子
int rchild;//右儿子
int parent;//父亲结点
char value;//该结点的值
}Tree[maxn];//
struct Tree_Code{
int bit[maxn];
int start;
}Code[maxn];//
void Huff_Tree()
{
int x1,x2;
double m1,m2;
for(int i=1;i<=n-1;i++)//产生n-1个新的结点
{
m1=Max;
m2=Max;
x1=0;
x2=0;
for(int j=1;j<n+i;j++)//每个结点都要和新产生的结点进行比较
{
if(Tree[j].weight<m1&&Tree[j].parent==-1)//本着左儿子小右儿子大的元则构建树
{
m2=m1;
x2=x1;
x1=j;
m1=Tree[j].weight;
}
else if(Tree[j].weight<m2&&Tree[j].parent==-1)
{
m2=Tree[j].weight;
x2=j;
}
}//for
Tree[x1].parent=i+n;//承上:要确定好结点的父亲
Tree[x2].parent=i+n;
Tree[i+n].lchild=x1;//启下:要确定该新结点赢具备的信息由两个儿子所给予
Tree[i+n].rchild=x2;
Tree[i+n].weight=m1+m2;
}//for