给定一组结点及对应的权值,创建一棵哈夫曼树,输出每个结点的哈夫曼编码,和整棵树的WPL值。用c++实现
时间: 2024-05-08 07:20:58 浏览: 192
用c++实现哈夫曼树
以下是C语言实现哈夫曼树的代码:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_NODE_NUM 1000
#define MAX_CODE_LEN 100
struct Node {
int weight;
int parent;
int lchild;
int rchild;
};
void create_huffman_tree(struct Node* nodes, int n);
void get_huffman_code(struct Node* nodes, int n, char (*code)[MAX_CODE_LEN], int* wpl);
void print_huffman_code(struct Node* nodes, char (*code)[MAX_CODE_LEN], int n, int wpl);
int main() {
int n;
struct Node nodes[MAX_NODE_NUM];
char code[MAX_NODE_NUM][MAX_CODE_LEN];
int wpl;
printf("请输入结点个数:");
scanf("%d", &n);
printf("请输入每个结点的权值:");
for (int i = 0; i < n; i++) {
scanf("%d", &nodes[i].weight);
nodes[i].parent = -1;
nodes[i].lchild = -1;
nodes[i].rchild = -1;
}
create_huffman_tree(nodes, n);
get_huffman_code(nodes, n, code, &wpl);
print_huffman_code(nodes, code, n, wpl);
return 0;
}
void create_huffman_tree(struct Node* nodes, int n) {
for (int i = 0; i < n - 1; i++) {
int min1 = -1, min2 = -1;
for (int j = 0; j < n; j++) {
if (nodes[j].parent == -1) {
if (min1 == -1 || nodes[j].weight < nodes[min1].weight) {
min2 = min1;
min1 = j;
} else if (min2 == -1 || nodes[j].weight < nodes[min2].weight) {
min2 = j;
}
}
}
nodes[min1].parent = n + i;
nodes[min2].parent = n + i;
nodes[n + i].weight = nodes[min1].weight + nodes[min2].weight;
nodes[n + i].lchild = min1;
nodes[n + i].rchild = min2;
}
}
void get_huffman_code(struct Node* nodes, int n, char (*code)[MAX_CODE_LEN], int* wpl) {
*wpl = 0;
for (int i = 0; i < n; i++) {
int p = nodes[i].parent;
int len = 0;
while (p != -1) {
if (nodes[p].lchild == i) {
code[i][len++] = '0';
} else {
code[i][len++] = '1';
}
p = nodes[p].parent;
}
code[i][len] = '\0';
*wpl += nodes[i].weight * len;
}
}
void print_huffman_code(struct Node* nodes, char (*code)[MAX_CODE_LEN], int n, int wpl) {
printf("哈夫曼编码为:\n");
for (int i = 0; i < n; i++) {
printf("%d: %s\n", nodes[i].weight, code[i]);
}
printf("WPL = %d\n", wpl);
}
```
在这个代码中,我们首先定义了一个 `Node` 结构体来表示哈夫曼树中的结点。其中,`weight` 表示结点的权值,`parent` 表示结点的父节点在数组中的下标,`lchild` 和 `rchild` 分别表示结点的左右子节点在数组中的下标。我们还定义了两个常量,`MAX_NODE_NUM` 表示最大结点数,`MAX_CODE_LEN` 表示哈夫曼编码的最大长度。
在 `main` 函数中,我们首先读入结点个数和每个结点的权值,并初始化每个结点的 `parent`、`lchild` 和 `rchild` 为 -1。然后调用 `create_huffman_tree` 函数创建哈夫曼树,调用 `get_huffman_code` 函数获取每个结点的哈夫曼编码和整棵树的 WPL 值,最后调用 `print_huffman_code` 函数输出结果。
`create_huffman_tree` 函数通过贪心策略构建哈夫曼树。具体来说,它每次从未被选择过的结点中选出权值最小的两个结点,将它们合并为一个新的结点,并将新结点的权值设为它们的权值之和,左右子节点分别为这两个结点。重复这个过程,直到所有结点都被合并成了一个根节点为止。
`get_huffman_code` 函数通过遍历哈夫曼树获取每个结点的哈夫曼编码,并计算整棵树的 WPL 值。具体来说,它对于每个结点,从它的父节点开始向上遍历,若当前结点是父节点的左子节点,则在编码字符串末尾添加一个 0,否则添加一个 1。重复这个过程,直到遍历到根节点为止。最后,将编码字符串翻转并存储到 `code` 数组中,同时累加每个结点的权值乘以编码长度,即为整棵树的 WPL 值。
`print_huffman_code` 函数将每个结点的权值和哈夫曼编码输出到屏幕上,并输出整棵树的 WPL 值。
阅读全文