哈夫曼树
题目描述:
本题要求实现一个创建哈夫曼树的函数,根据输入的n个结点的权值,创建一棵哈夫曼树。
输入样例:
5 2 3 5 7 8
输出样例:
5(2,3),10(5,5),15(7,8),25(10,15),
代码:
#include <stdio.h>
#include <string.h>
#include <malloc.h>
typedef struct
{
int weight; //权重
int parent; //双亲结点
int lc, rc; //左右子节点
} HTNode, *HuffmanTree;
void Select(HuffmanTree *HT,int n,int *s1,int *s2) //找出子树中权值最小的两个数
{
int min; // 定义一个临时变量保存最小值
for(int i=1;i<=n;i++) //以下是找到第一个最小值
{
if((*HT)[i].parent==0)
{
min = i;
break;
}
}
for(int i=1;i<=n;i++)
{
if((*HT)[i].parent==0)
if((*HT)[i].weight<(*HT)[min].weight)
min=i;
}
*s1 = min; //以下是找到第二个最小值,且与第一个不同
for(int i=1;i<=n;i++)
{
if((*HT)[i].parent==0&&i!=*s1)
{
min=i;
break;
}
}
for(int i=1;i<=n;i++)
{
if((*HT)[i].parent==0&&i!=*s1)
if((*HT)[i].weight<(*HT)[min].weight)
min=i;
}
*s2=min;
}
void CreatHuff(HuffmanTree *HT, int *w, int n)
{
int s1,s2;
int m=2*n-1;
(*HT)=(HuffmanTree)malloc((m)*sizeof(HTNode)); //申请空间储存初始的子树和合并后的二叉树
for(int i=1;i<=n;i++) //将初始的二叉树赋值到新申请的空间
(*HT)[i].weight=w[i];
for(int i=n+1;i<m;i++) //将存放合并后二叉树的空间全部初始化为 1
(*HT)[i].weight=0;
for(int i=n+1;i<=m;i++)
{
Select(HT,i-1,&s1,&s2); //选出权值最小的两个子树进行合并
(*HT)[i].weight=(*HT)[s1].weight+(*HT)[s2].weight; //将权值相加作为节点存储起来
(*HT)[s1].parent=i; //将两个子树的双亲结点全部赋值
(*HT)[s2].parent=i;
(*HT)[i].lc=s1; //将双亲节点的左右子节点全部赋值
(*HT)[i].rc=s2;
printf("%d(%d,%d),",(*HT)[i].weight,(*HT)[s1].weight,(*HT)[s2].weight);
}
}
int main()
{
HuffmanTree HT;
int *w, n, wei,i;
scanf("%d", &n);
w=(int *)malloc((n+1)*sizeof(int)); //用于存储输入的结点值
for(i=1;i<=n;i++)
{
scanf("%d",&wei);
w[i]=wei;
}
CreatHuff(&HT, w, n);
return 0;
}