内容
1、创建一棵哈夫曼树,顺序存储方式
2、可键盘输入叶子结点的权值
3、输出各节点的权值、父母域、左右孩子域
代码
#include<stdio.h>
#include<stdlib.h>
typedef struct
{
int weight;
int parent,lchild,rchild;
}HTNode,*HuffmanTree;
void CreateHuffmanTree(HuffmanTree *HT,int n);
int Select(HuffmanTree *HT,int i);
int main()
{
int i;
HuffmanTree HT;
int n;
printf("请输入哈夫曼树的叶子节点的个数:");
scanf("%d",&n);
CreateHuffmanTree(&HT,n);
for(i=1;i<2*n;i++) //输出各节点的权值、父母域、左右孩子域
{
printf("结点序号%4d\t权重%4d\tparent%4d\tlchild%4d\trchild%4d\t\n",i,HT[i].weight,HT[i].parent,HT[i].lchild,HT[i].rchild);
}
return 0;
}
/*函数:void CreateHuffmanTree(HuffmanTree *HT,int n)
作用:构造一棵哈夫曼树
输入:HuffmanTree数组的首地址和叶子结点的个数n*/
void CreateHuffmanTree(HuffmanTree *HT,int n)
{
HuffmanTree *T;
int m;
int i;
int s1,s2;
if(n<=1)
return;
m=2*n-1;
*HT=(HuffmanTree)malloc(sizeof(HTNode)*(m+1)); //0号单元未用,所以需要动态分配m+1个单元,HT[m]表示根结点
T=HT;
for(i=1;i<=m;++i) //将1~m号单元中的双亲、左孩子、右孩子的下标都初始化为0
{
(*HT)[i].parent=0;
(*HT)[i].lchild=0;
(*HT)[i].rchild=0;
}
printf("请输入每个叶子结点的权值:");
for(i=1;i<=n;i++) //输入前n个单元中叶子结点的权值
{
scanf("%d",&(*HT)[i].weight);
/*--------------------------初始化工作结束,下面开始创建哈夫曼树---------------------------------------*/
printf("%d\t",(*HT)[i].weight);
}
printf("\n");
for(i=n+1;i<=m;++i)
{//通过n-1次的选择、删除、合并来创建哈夫曼树
s1=Select(T,i-1);
(*HT)[s1].parent=i;
s2=Select(T,i-1);
(*HT)[s2].parent=i; //得到新结点i,从森林中删除s1、s2,将s1、s2的双亲域由0改为i
(*HT)[i].lchild=s1;
(*HT)[i].rchild=s2; //s1、s2分别作为i的左右孩子
(*HT)[i].weight=(*HT)[s1].weight+(*HT)[s2].weight; //i的权值为左右孩子权值之和
}
}
/*函数:int Select(HuffmanTree *HT,int i)
作用:在[k](1<=k<=i)中选择两个其双亲域为0且权值最小的结点,并返回他们的在HT中的序号的地址,s1,s2
输入:HuffmanTree数组的首地址和在[k](1<=k<=i-1)中选择两个其双亲域为0且权值最小的结点,并返回他们的在HT中的序号*/
int Select(HuffmanTree *HT,int i)
{
int k,s;
int MIN=100;
for(k=1;k<=i;++k)
{
if((*HT)[k].parent==0)
{
if((*HT)[k].weight<MIN)
{
MIN=(*HT)[k].weight; //找出权重最小的
s=k; //s存放他的序号
}
}
}
return s;
}