注:哈夫曼树的详细学习与解析请移步到其他专业人士的文章中进行学习,此文章只提供完整运行代码
运行效果图:
完整代码:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MAX_SIZE 1000
struct HuffmanTreeNode {
int weight;
int lchild, rchild, parent;
};
// select函数 选出哈夫曼树中权重最小的两个数
void select(HuffmanTreeNode *HT,int m,int *s1,int *s2) {
int i,min1=MAX_SIZE, min2=MAX_SIZE;
for(i=1; i<=m; i++) {
if(HT[i].parent==0&&min1>HT[i].weight&&HT[i].weight!=0) {
min1=HT[i].weight;
*s1=i;
}
}
for(i=1; i<=m; i++) {
if(i!=(*s1)&&HT[i].parent==0&&HT[i].weight!=0) {
if(HT[i].weight<min2) {
min2=HT[i].weight;
*s2=i;
}
}
}
}
// 哈夫曼树的建立
int HuffmanTree(int n) {
int m,i,q1,q2,cache;
char result[MAX_SIZE],str[MAX_SIZE];
struct HuffmanTreeNode *HT;
m=2*n-1;
HT=(struct HuffmanTreeNode *)malloc((m+1)*sizeof(struct HuffmanTreeNode));
for(i=1; i<=n; i++) {
scanf("%d",&HT[i].weight);
HT[i].parent=0;
HT[i].lchild=0;
HT[i].rchild=0;
}
printf("\n");
// 哈夫曼树的初始化
for(i=n+1; i<=m; i++) {
HT[i].weight = 0;
HT[i].lchild = 0;
HT[i].rchild = 0;
HT[i].parent = 0;
}
printf("哈夫曼树雏形:\n");
for(i=1; i<=m; i++) {
printf("%d\t%d\t%d\t%d\n",HT[i].weight,HT[i].parent,HT[i].lchild,HT[i].rchild);
}
// 哈夫曼两个最小值
for(i=n+1; i<=m; i++) {
select(HT,m,&q1,&q2);
HT[i].weight = HT[q1].weight + HT[q2].weight;
HT[q1].parent = i ;
HT[q2].parent = i;
HT[i].lchild = q1;
HT[i].rchild = q2;
HT[i].parent = 0;
}
printf("哈夫曼树:\n");
for(i=1; i<=m; i++) {
printf("%d\t%d\t%d\t%d\n",HT[i].weight,HT[i].parent,HT[i].lchild,HT[i].rchild);
}
printf("\n");
// 哈夫曼编码
printf("哈夫曼编码:\n");
for(i=1; i<=n; i++) {
cache = i;
while(HT[cache].parent) {
if(HT[HT[cache].parent].lchild == cache) {
strcpy(str,"0");
} else if(HT[HT[cache].parent].rchild == cache) {
strcpy(str,"1");
}
cache = HT[cache].parent;
strcat(str,result);
strcpy(result, str);
memset(str, 0, sizeof(str));
}
printf("%d的哈夫曼编码为:%s",HT[i].weight,result);
memset(result, 0, sizeof(result));
printf("\n");
}
return 0;
}
int main() {
int leaf;
printf("请输入叶子节点个数:");
scanf("%d",&leaf);
printf("请依次输入叶子结点值:\n");
HuffmanTree(leaf);
return 0;
}