规则是:
hulfman树是在编码的时候使用的最优二叉树,组建规则是每次根据权值数组中的数据,选取最小的两个权值组成一颗小树,然后得到一个新的权值再放入权值数组,再继续重复该操作直到所有初始的节点都使用了一遍。
并且由于是满二叉树,所以Hulfman树有以下规律:
输入的权值数据都是叶子节点,并且整棵树的节点数 = 2 * 叶子节点数 -1
hulfman树使用的是连续的存储结构来实现:
typedef struct node{
char data;
int weight;
int father,lchild,rchild;
int flag; //用来找最小额两个数值的函数要使用的标志量,将之前已经使用过的节点打上标记。
}Hulfman;
void FindMin(Hulfman *Hulf,int n,int *Min_1,int *Min_2)
{
int temp,k = 0;
while(Hulf[k++].flag != -1);
(*Min_1) = k-1;
while(Hulf[k++].flag != -1);
(*Min_2) = k-1;
if(Hulf[(*Min_1)].weight > Hulf[(*Min_2)].weight)
{
temp = (*Min_1);
(*Min_1) = (*Min_2);
(*Min_2) = temp;
}
for(int i = k;i < n;i++)
{
if(Hulf[i].weight < Hulf[*Min_1].weight && Hulf[i].flag == -1)
{
(*Min_2) = (*Min_1);
(*Min_1) = i;
}//end of if
else if(Hulf[i].weight >= Hulf[*Min_1].weight && Hulf[i].flag == -1)
{
if(Hulf[i].weight < Hulf[*Min_2].weight && Hulf[i].flag == -1)
(*Min_2) = i;
}
}//end of for
}
void CreateHulfman(Hulfman *HulfmanTree,char *data,int *weight,int NodeNumber,int LeafNodeNumber)
{
for(int i = 0;i < LeafNodeNumber;i++)
{
HulfmanTree[i].data = data[i];
HulfmanTree[i].weight = weight[i];
HulfmanTree[i].flag = -1;
HulfmanTree[i].lchild = HulfmanTree[i].rchild = -1;
}
int Min_1,Min_2,count;
count = LeafNodeNumber;
for(i = 1;i < LeafNodeNumber;i++)
{
FindMin(HulfmanTree,count,&Min_1,&Min_2);
HulfmanTree[count].data = '#';
HulfmanTree[count].flag = -1;
HulfmanTree[count].lchild = Min_1;
HulfmanTree[count].rchild = Min_2;
HulfmanTree[count].weight = HulfmanTree[Min_1].weight+HulfmanTree[Min_2].weight;
HulfmanTree[Min_1].father = count;
HulfmanTree[Min_2].father = count;
HulfmanTree[Min_1].flag = 1;
HulfmanTree[Min_2].flag = 1;
count++;
}
}
void Travel(Hulfman *Hulf,int NodeNumber)
{
printf("数据是:%c,权值是:%d\n",Hulf[NodeNumber].data,Hulf[NodeNumber].weight);
if(Hulf[NodeNumber].lchild != -1)
Travel(Hulf,Hulf[NodeNumber].lchild);
if(Hulf[NodeNumber].rchild != -1)
Travel(Hulf,Hulf[NodeNumber].rchild);
}