#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#define MAXLEN 100
typedef struct {
int weight;//定义一个整形权值变量
int lchild, rchild, parent;//定义左,右孩子及双亲指针
}HTNode;
typedef HTNode HT[MAXLEN];//向量类型
int n;
//哈夫曼树初始化函数
void InitHFMT(HT T) {
printf("\n请输入共有多少个权值(小于100):");
scanf("%d", &n);
int i = 0;
for (i = 0; i < 2 * n - 1; i++) {
T[i].weight = 0;
T[i].lchild = -1;
T[i].rchild = -1;
T[i].parent= -1;
}
}
//输入权值函数
void InputWeight(HT T) {
int w = 0, i = 0;
for (i = 0; i < n; i++) {
printf("输入第%d个权值:", i + 1);
scanf("%d", &w);
getchar();
T[i].weight = w;
}
}
//选择两个结点中小的结点
void SelectMin(HT T, int i, int* p1, int* p2) {
/*预设两个值,并使它大于可能出现的最大权值*/
long min1 = 888888, min2 = 888888;
int j = 0;
for (j = 0; j <=i; j++) {
if (T[j].parent == -1) {
if (min1 > T[j].weight) {
min1 = T[j].weight;//找出最小的权值
*p1 = j;//通过*p1带回序号
}
}
}
for (j = 0; j <= i; j++) {
if (T[j].parent == -1) {
if (min2 > T[j].weight&&j!=(*p1)) {
min2 = T[j].weight;//找出次最小的权值
*p2 = j;//通过*p2带回序号
}
}
}
}
//构造哈夫曼树,T[2*n-1]为其根结点
void CreatHFMT(HT T) {
int i=0, p1, p2;
InitHFMT(T);
InputWeight(T);
for (i = n; i < 2 * n - 1; i++) {
SelectMin(T, i - 1, &p1, &p2);
T[p1].parent = T[p2].parent = i;
T[i].lchild = T[p1].weight;
T[i].rchild = T[p2].weight;
T[i].weight = T[p1].weight + T[p2].weight;
}
}
//输出向量状态表
void PrintHFMT(HT T) {
printf("\n哈夫曼树的各边显示:\n");
int i = 0;
for (i = 0; i < 2 * n - 1; i++) {
while (T[i].lchild != -1) {
printf("(%d,%d),(%d,%d)\n",
T[i].weight, T[i].lchild, T[i].weight, T[i].rchild);
break;
}
}
}
//哈夫曼编码函数
void hfnode(HT T, int i, int j) {
j = T[i].parent;
if (T[j].rchild == T[i].weight)
printf("1");
else
printf("0");
if (T[j].parent != -1) {
i = j;
hfnode(T, i, j);
}
}
//求哈夫曼编码
void huffmannode(HT T) {
printf("\n输入的权值对应的哈夫曼编码:");
int i = 0, j = 0, a;
for (i = 0; i < n; i++) {
j = 0;//
a = i;
printf("\n%i的编码为:", T[i].weight);
hfnode(T, i, j);
i = a;
}
}
int main() {
HT HT;
CreatHFMT(HT);
PrintHFMT(HT);
huffmannode(HT);
return 0;
}
运行结果