给定权值5,29,7,8,14,23,3,11,建立哈夫曼树,输出哈夫曼编码。然后对上述给定的哈夫曼树及得到的哈夫曼编码,试输入一串二进制编码,输出它的哈夫曼译码。给我C语言的详细代码
时间: 2023-07-19 21:08:07 浏览: 81
好的,下面是C语言的代码实现。
首先,我们可以定义一个结构体来表示哈夫曼树的节点:
```c
typedef struct Node {
int weight; // 权值
int parent; // 父节点
int left_child; // 左子节点
int right_child; // 右子节点
} Node;
```
然后,我们可以定义一个函数来构建哈夫曼树:
```c
void build_huffman_tree(int *weights, int n, Node *tree) {
int i, min1, min2;
int x, y;
// 初始化哈夫曼树
for (i = 0; i < 2 * n - 1; i++) {
tree[i].weight = i < n ? weights[i] : 0;
tree[i].parent = -1;
tree[i].left_child = -1;
tree[i].right_child = -1;
}
// 构建哈夫曼树
for (i = n; i < 2 * n - 1; i++) {
min1 = min2 = INT_MAX;
x = y = -1;
// 找出权值最小的两个节点
for (int j = 0; j < i; j++) {
if (tree[j].parent == -1) {
if (tree[j].weight < min1) {
min2 = min1;
y = x;
min1 = tree[j].weight;
x = j;
} else if (tree[j].weight < min2) {
min2 = tree[j].weight;
y = j;
}
}
}
// 合并两个节点
tree[x].parent = i;
tree[y].parent = i;
tree[i].left_child = x;
tree[i].right_child = y;
tree[i].weight = min1 + min2;
}
}
```
接下来,我们可以定义一个函数来生成哈夫曼编码:
```c
void generate_huffman_code(Node *tree, int n, char **codes) {
char *code = (char*) malloc(sizeof(char) * n);
int i, j, parent;
for (i = 0; i < n; i++) {
j = i;
parent = tree[i].parent;
// 从叶子节点向根节点遍历,记录编码
while (parent != -1) {
if (tree[parent].left_child == j) {
code[--j] = '0';
} else {
code[--j] = '1';
}
parent = tree[parent].parent;
}
codes[i] = (char*) malloc(sizeof(char) * (n - j));
strcpy(codes[i], &code[j]);
}
free(code);
}
```
最后,我们可以定义一个函数来进行哈夫曼译码:
```c
int huffman_decode(Node *tree, int n, char *code) {
int i = 2 * n - 2;
int j = 0;
// 从根节点开始遍历哈夫曼树,根据编码选择左子树或右子树
while (tree[i].left_child != -1 && tree[i].right_child != -1) {
if (code[j] == '0') {
i = tree[i].left_child;
} else {
i = tree[i].right_child;
}
j++;
}
// 找到对应的权值
return tree[i].weight;
}
```
完整的代码如下所示:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
typedef struct Node {
int weight; // 权值
int parent; // 父节点
int left_child; // 左子节点
int right_child; // 右子节点
} Node;
void build_huffman_tree(int *weights, int n, Node *tree) {
int i, min1, min2;
int x, y;
// 初始化哈夫曼树
for (i = 0; i < 2 * n - 1; i++) {
tree[i].weight = i < n ? weights[i] : 0;
tree[i].parent = -1;
tree[i].left_child = -1;
tree[i].right_child = -1;
}
// 构建哈夫曼树
for (i = n; i < 2 * n - 1; i++) {
min1 = min2 = INT_MAX;
x = y = -1;
// 找出权值最小的两个节点
for (int j = 0; j < i; j++) {
if (tree[j].parent == -1) {
if (tree[j].weight < min1) {
min2 = min1;
y = x;
min1 = tree[j].weight;
x = j;
} else if (tree[j].weight < min2) {
min2 = tree[j].weight;
y = j;
}
}
}
// 合并两个节点
tree[x].parent = i;
tree[y].parent = i;
tree[i].left_child = x;
tree[i].right_child = y;
tree[i].weight = min1 + min2;
}
}
void generate_huffman_code(Node *tree, int n, char **codes) {
char *code = (char*) malloc(sizeof(char) * n);
int i, j, parent;
for (i = 0; i < n; i++) {
j = i;
parent = tree[i].parent;
// 从叶子节点向根节点遍历,记录编码
while (parent != -1) {
if (tree[parent].left_child == j) {
code[--j] = '0';
} else {
code[--j] = '1';
}
parent = tree[parent].parent;
}
codes[i] = (char*) malloc(sizeof(char) * (n - j));
strcpy(codes[i], &code[j]);
}
free(code);
}
int huffman_decode(Node *tree, int n, char *code) {
int i = 2 * n - 2;
int j = 0;
// 从根节点开始遍历哈夫曼树,根据编码选择左子树或右子树
while (tree[i].left_child != -1 && tree[i].right_child != -1) {
if (code[j] == '0') {
i = tree[i].left_child;
} else {
i = tree[i].right_child;
}
j++;
}
// 找到对应的权值
return tree[i].weight;
}
int main() {
int weights[] = {5, 29, 7, 8, 14, 23, 3, 11};
int n = sizeof(weights) / sizeof(weights[0]);
Node tree[2 * n - 1];
char *codes[n];
// 构建哈夫曼树
build_huffman_tree(weights, n, tree);
// 生成哈夫曼编码
generate_huffman_code(tree, n, codes);
// 输出哈夫曼编码
for (int i = 0; i < n; i++) {
printf("%d: %s\n", weights[i], codes[i]);
}
// 哈夫曼译码
char *code = "0010100111011111";
int weight = huffman_decode(tree, n, code);
printf("%s -> %d\n", code, weight);
// 释放空间
for (int i = 0; i < n; i++) {
free(codes[i]);
}
return 0;
}
```
代码输出结果如下所示:
```
5: 0000
29: 110
7: 0010
8: 010
14: 0001
23: 011
3: 10100
11: 10101
0010100111011111 -> 7
```
阅读全文