功能模块设计

基于C语言实现的哈夫曼树,包含以下功能模块:

  • 创建哈夫曼树
  • 输出所有节点的权值
  • 通过递归求解哈夫曼编码
  • 通过循环求解哈夫曼编码

完整代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXLEAF 1000 //最多叶子节点数
#define MAXVALUE 2147483647 //最大权值

/*哈夫曼树的数据结构*/
typedef struct
{
int weight; //权值
int parent; //父节点下标
int lchild; //左孩子节点的下标
int rchild; //右孩子节点的下标
} HNodeType;

/*函数声明列表*/
void HuffmanTree(HNodeType HuffNode[], int n); //1 创建哈夫曼树
void Output(HNodeType HuffNode[], int n); //2 输出所有节点的权值
void GetCode1(HNodeType HuffNode[], int i, char dest[], int len); //3 通过递归求哈夫曼编码
void GetCode2(HNodeType HuffNode[], int n); //4 通过循环求哈夫曼编码

int main(void)
{
int n = 7;
printf("输入节点个数:");
scanf("%d", &n);
printf("输入各节点的权值:");
HNodeType HuffNode[MAXLEAF];
HuffmanTree(HuffNode, n);
printf("所有节点权值:");
Output(HuffNode, n);
char dest[MAXLEAF] = "";
printf("\n通过递归求各节点哈夫曼编码:\n");
printf("%-8s%-10s\n", "权值", "编码");
GetCode1(HuffNode, 2 * n - 2, dest, 0);
printf("\n通过循环求各节点哈夫曼编码:\n");
printf("%-8s%-10s\n", "权值", "编码");
GetCode2(HuffNode, n);
printf("\n");
return 0;
}

/*函数实现部分*/
/*【功能1 创建哈夫曼树】*/
void HuffmanTree(HNodeType HuffNode[], int n)
{
int i = 0, j = 0;
for (i = 0; i < 2 * n - 1; i++)
{
HuffNode[i].weight = 0;
HuffNode[i].parent = -1;
HuffNode[i].lchild = -1;
HuffNode[i].rchild = -1;
}
for (i = 0; i < n; i++) scanf("%d", &HuffNode[i].weight);
//找最小值和次小值
for (i = 0; i < n - 1; i++)
{
int m1 = MAXVALUE, m2 = MAXVALUE, x1 = -1, x2 = -1;
for (j = 0; j < n + i; j++)
{
if (HuffNode[j].weight < m1 && HuffNode[j].parent == -1)
{
m2 = m1;
x2 = x1;
m1 = HuffNode[j].weight;
x1 = j;
}
else if (HuffNode[j].weight < m2 && HuffNode[j].parent == -1)
{
m2 = HuffNode[j].weight;
x2 = j;
}
}
//选中x1,x2合并
HuffNode[n + i].weight = m1 + m2;
HuffNode[n + i].lchild = x1;
HuffNode[n + i].rchild = x2;
HuffNode[x1].parent = n + i;
HuffNode[x2].parent = n + i;
}
}

/*【功能2 输出所有节点的权值】*/
void Output(HNodeType HuffNode[], int n)
{
int i = 0;
for (i = 0; i < 2 * n - 1; i++)
{
printf("%d ", HuffNode[i].weight);
}
printf("\n");
}

/*【功能3 通过递归求哈夫曼编码】*/
void GetCode1(HNodeType HuffNode[], int i, char dest[], int len)
{
if (HuffNode[i].lchild == -1 && HuffNode[i].rchild == -1)
{
dest[len] = '\0';
printf("%-8d%-10s\n", HuffNode[i].weight, dest);
return;
}
if (HuffNode[i].lchild != -1)
{
dest[len] = '0';
GetCode1(HuffNode, HuffNode[i].lchild, dest, len + 1);
}
if (HuffNode[i].rchild != -1)
{
dest[len] = '1';
GetCode1(HuffNode, HuffNode[i].rchild, dest, len + 1);
}
}

/*【功能4 通过循环求哈夫曼编码】*/
void GetCode2(HNodeType HuffNode[], int n)
{
int i = 0;
for (i = 0; i < n; i++)
{
int c = i, f = 0, j = 0;
int code[MAXLEAF] = { 0 }; //编码数组
int len = 0;
f = HuffNode[c].parent;
while (f >= 0)
{
if (HuffNode[f].lchild == c) code[len++] = 0;
else code[len++] = 1;
c = f;
f = HuffNode[c].parent;
}
printf("%-8d", HuffNode[i].weight);
for (j = len - 1; j >= 0; j--) printf("%d", code[j]);
printf("\n");
}
}

运行方法

  1. 新建一个cpp文件,命名为”main.cpp”。
  2. 将完整代码复制粘贴至”main.cpp”中。
  3. 利用Dev C++运行”main.cpp”即可。

运行结果

运行结果