#include <stdio.h>
#include<stdlib.h>
#include <conio.h>
#include <string.h>
#define n 5 // 定义哈夫曼树中叶子节点个数
#define m 9 // 哈夫曼树结点用一个大小为2n-1 的向量存储
typedef struct
{
int weight; // 定义权值域
int lchild, rchild, parent;
}HTNode;
typedef HTNode HuffmanTree[m]; // 声明结构体数组
// 初始化函数
void InitHuffmanTree(HuffmanTree T)
{
int i;
for ( i = 0; i < m; i++)
{
T[i].weight = 0;
T[i].lchild = -1;
T[i].rchild = -1;
T[i].parent = -1;
}
}
// 输入权值函数
void InputWeight(HuffmanTree T)
{
int i;
int w[n] = {7,6,12,15,10};
for (int i = 0; i < n; i++)
{
// printf("\n 输入第%d个权值:", i + 1);
// scanf_s("%d", &w);
T[i].weight = w[i];
}
}
// 选择两个权值最小的根节点函数
void SelectMin(HuffmanTree T, int i, int *p1, int *p2)
{
int min1 = INT_MAX; // 标记作用 定义并初始化最小权值
int min2 = INT_MAX; // 标记作用 定义并初始化次小权值
int j;
for ( j = 0; j <= i; j++)
if (T[j].parent == -1)
{
if (T[j].weight < min1)
{
min2 = min1; // 改变次小的权值标记
min1 = T[j].weight; // 改变最小的权值标记
*p2 = *p1; // 改变次小权值节点的位置
*p1 = j; // 改变最小权值节点的位置
}
else if (T[j].weight < min2)
{
min2 = T[j].weight; // 改变次小权值的标记
*p2 = j; // 改变次小权值的节点位置
}
}
}
// 构造哈夫曼树
int main()
{
int i=0, p1=0, p2=0;
char k = '#';
HuffmanTree T;
InitHuffmanTree(T);
InputWeight(T);
printf("初始化结点位置为:");
printf("\n");
for (int i = 0; i < n; i++)
{
printf("%4d", i);
}
printf("\n");
printf("初始化结点位置对应的权值为依次为:\n");
for (int i = 0; i < n; i++)
{
printf("%4d",T[i].weight);
}
printf("\n");
printf("\n");
printf("哈夫曼合并过程 使用过的结点用‘#’代表:");
printf("\n");
for ( i = n; i < m; i++)
{
for (int j= 0; j < m; j++)
{
if (T[j].parent != -1)
{
printf("%4c", k);
}
else
{
printf("%4d", T[j].weight);
}
}
printf("\n");
SelectMin(T, i - 1, &p1, &p2);
T[p1].parent = T[p2].parent = i;
T[i].lchild = p1;
T[i].rchild = p2;
T[i].weight = T[p1].weight + T[p2].weight;
}
//getchar();
printf("\n");
printf("\n");
printf("结点位置:");
printf("\n");
for (int i = 0; i < m; i++)
{
printf("%4d", i);
}
printf("\n");
printf("\n");
printf("对应的权值依次为:");
printf("\n");
for ( int i = 0; i < m; i++)
{
printf("%4d",T[i].weight);
}
getchar();
getchar();
}
效果图如下: