给定n个叶子节点及其对应的权值,构造相应的哈夫曼树及叶子节点的哈夫曼编码。输入3行数据:第一行为叶子节点个数;第二行为各叶子节点代表的单词(单词最长为4个字符);第二行为各叶子节点代表的单词的权值。C语言
时间: 2024-05-16 13:14:32 浏览: 99
以下是C语言实现哈夫曼树构建和编码的示例代码:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_LEN 4 // 单词最大长度
// 哈夫曼树结点
typedef struct node {
char word[MAX_LEN + 1]; // 单词
int weight; // 权值
struct node *left; // 左子树
struct node *right; // 右子树
} Node;
// 哈夫曼编码表结点
typedef struct code {
char word[MAX_LEN + 1]; // 单词
char *code; // 编码
struct code *next; // 下一个结点
} Code;
// 比较函数
int cmp(const void *a, const void *b) {
return ((Node *)a)->weight - ((Node *)b)->weight;
}
// 创建哈夫曼树
Node *create_huff_tree(Node *nodes, int n) {
int i, j;
Node *root;
for (i = 0; i < n - 1; i++) {
// 找到权值最小的两个结点
int min1 = -1, min2 = -1;
for (j = 0; j < n + i; j++) {
if (nodes[j].weight > 0) {
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;
}
}
}
// 合并两个结点
root = (Node *)malloc(sizeof(Node));
root->weight = nodes[min1].weight + nodes[min2].weight;
root->left = &nodes[min1];
root->right = &nodes[min2];
nodes[min1].weight = -1;
nodes[min2].weight = root->weight;
nodes[n + i] = *root;
}
return &nodes[n * 2 - 2];
}
// 递归生成哈夫曼编码
void generate_code(Node *root, Code *head, char *path) {
if (root->left == NULL && root->right == NULL) {
// 叶子结点,添加编码
Code *node = (Code *)malloc(sizeof(Code));
strcpy(node->word, root->word);
node->code = strdup(path);
node->next = head->next;
head->next = node;
} else {
// 非叶子结点,生成编码
char left_path[MAX_LEN * 2 + 1];
char right_path[MAX_LEN * 2 + 1];
sprintf(left_path, "%s0", path);
sprintf(right_path, "%s1", path);
generate_code(root->left, head, left_path);
generate_code(root->right, head, right_path);
}
}
// 输出哈夫曼编码表
void print_code_table(Code *head) {
printf("Word\tCode\n");
printf("----\t----\n");
for (Code *p = head->next; p != NULL; p = p->next) {
printf("%s\t%s\n", p->word, p->code);
}
}
int main() {
int n, i;
Node nodes[MAX_LEN * 2];
Code code_head = {"", "", NULL};
// 读入数据
scanf("%d", &n);
for (i = 0; i < n; i++) {
scanf("%s", nodes[i].word);
}
for (i = 0; i < n; i++) {
scanf("%d", &nodes[i].weight);
nodes[i].left = nodes[i].right = NULL;
}
// 构建哈夫曼树
qsort(nodes, n, sizeof(Node), cmp);
Node *root = create_huff_tree(nodes, n);
// 生成哈夫曼编码
generate_code(root, &code_head, "");
// 输出哈夫曼编码表
print_code_table(&code_head);
return 0;
}
```
输入示例:
```
4
a b c d
1 2 4 8
```
输出示例:
```
Word Code
---- ----
d 0
c 10
b 110
a 111
```
阅读全文