哈夫曼树又称最优二叉树,是一种带权路径长度最短的二叉树。所谓树的带权路径长度,就是树中所有的叶结点的权值乘上其到根结点的路径长度(若根结点为0层,叶结点到根结点的路径长度为叶结点的层数)。树的路径长度是从树根到每一结点的路径长度之和,记为WPL=(W1*L1+W2*L2+W3*L3+...+Wn*Ln),N个权值Wi(i=1,2,...n)构成一棵有N个叶结点的二叉树,相应的叶结点的路径长度为Li(i=1,2,...n)。可以证明哈夫曼树的WPL是最小的。
代码实现:
#include<stdio.h>
#include<stdlib.h>
typedef struct node{
char word;
int weight;
struct node *left;
struct node *right;
}HuffNode;
//创建哈夫曼树
HuffNode* CreateHuffmantree(HuffNode** F,int n){
int i,loop,k1,k2; //k1存放最小值,k2存放次小值
HuffNode *pa;
for(loop=1;loop<n;loop++){
for(k1=0;k1<n&&!F[k1];k1++); //遍历森林找到第一个非空的树
for(k2=k1+1;k2<n&&!F[k2];k2++); //遍历森林找到第二个非空的树
for(i=k2;i<n;i++){ //寻找weight值最小和次小的两棵树,k1为最小下标,k2为次小的下标
if(F[i]){
if(F[i]->weight<F[k1]->weight){
k2=k1;
k1=i;
}else if(F[i]->weight<F[k2]->weight){
k2=i;
}
}
}
pa=(HuffNode*)malloc(sizeof(HuffNode)); //创建结点,把F[k1]和F[k2]挂到pa上
pa->weight=F[k1]->weight+F[k2]->weight;
pa->word='X';
pa->left=F[k1];
pa->right=F[k2];
F[k1]=pa;
F[k2]=NULL;
}
return F[k1];
}
//前序遍历输出哈夫曼树
void PrintLink(HuffNode* root){
if(root){
printf("%c %d ",root->word,root->weight);
PrintLink(root->left);
PrintLink(root->right);
}
}
int main(void){
HuffNode *root;
int n;
printf("请输入需要传输不同字符的个数:\n");
scanf("%d",&n);
fflush(stdin);
HuffNode** F;
F=(HuffNode**)malloc(n*sizeof(HuffNode*));
for(int i=0;i<n;i++){
F[i]=(HuffNode*)malloc(sizeof(HuffNode));
F[i]->left=F[i]->right=NULL;
printf("请输入传输的字符:");
scanf("%c",&F[i]->word);
fflush(stdin);
printf("请输入传输的频率:");
scanf("%d",&F[i]->weight);
fflush(stdin);
}
root=CreateHuffmantree(F,n); //创建哈夫曼树
PrintLink(root); //前序遍历输出哈夫曼树
}
运行结果如下: