请用C语言模拟实现哈夫曼编码,要求输入一个关键词的频率表,输出相应的每个关键词的编码
时间: 2024-05-16 09:18:20 浏览: 65
以下是用C语言模拟实现哈夫曼编码的示例代码:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_LEN 100
// 定义哈夫曼树结点
typedef struct TreeNode {
char key; // 关键词
int freq; // 出现频率
struct TreeNode *left; // 左孩子
struct TreeNode *right; // 右孩子
} TreeNode;
// 定义哈夫曼编码结点
typedef struct CodeNode {
char key; // 关键词
char code[MAX_LEN]; // 编码
} CodeNode;
// 比较函数,用于qsort排序
int cmp(const void *a, const void *b) {
return ((TreeNode *)a)->freq - ((TreeNode *)b)->freq;
}
// 创建哈夫曼树
TreeNode *createHuffmanTree(char *keys, int *freqs, int n) {
TreeNode **nodes = (TreeNode **)malloc(sizeof(TreeNode *) * n); // 动态分配结点数组
for (int i = 0; i < n; i++) {
nodes[i] = (TreeNode *)malloc(sizeof(TreeNode));
nodes[i]->key = keys[i];
nodes[i]->freq = freqs[i];
nodes[i]->left = nodes[i]->right = NULL;
}
while (n > 1) {
qsort(nodes, n, sizeof(TreeNode *), cmp); // 按照出现频率从小到大排序
TreeNode *newNode = (TreeNode *)malloc(sizeof(TreeNode));
newNode->key = '\0';
newNode->freq = nodes[0]->freq + nodes[1]->freq;
newNode->left = nodes[0];
newNode->right = nodes[1];
nodes[1] = newNode;
n--;
}
return nodes[0];
}
// 释放哈夫曼树
void freeHuffmanTree(TreeNode *root) {
if (root != NULL) {
freeHuffmanTree(root->left);
freeHuffmanTree(root->right);
free(root);
}
}
// 按照哈夫曼树遍历编码
void traverseHuffmanTree(TreeNode *root, char *code, int len, CodeNode *codes, int *cnt) {
if (root == NULL) {
return;
}
if (root->left == NULL && root->right == NULL) { // 叶子结点
codes[*cnt].key = root->key;
strncpy(codes[*cnt].code, code, len); // 拷贝编码
codes[*cnt].code[len] = '\0'; // 添加字符串结束符
(*cnt)++;
} else {
code[len] = '0'; // 左子树编码为0
traverseHuffmanTree(root->left, code, len + 1, codes, cnt);
code[len] = '1'; // 右子树编码为1
traverseHuffmanTree(root->right, code, len + 1, codes, cnt);
}
}
int main() {
char keys[] = {'a', 'b', 'c', 'd', 'e'};
int freqs[] = {7, 5, 2, 4, 8};
int n = sizeof(keys) / sizeof(keys[0]);
TreeNode *root = createHuffmanTree(keys, freqs, n);
CodeNode codes[MAX_LEN];
int cnt = 0;
char code[MAX_LEN];
traverseHuffmanTree(root, code, 0, codes, &cnt);
printf("关键词\t频率\t编码\n");
for (int i = 0; i < cnt; i++) {
printf("%c\t%d\t%s\n", codes[i].key, freqs[i], codes[i].code);
}
freeHuffmanTree(root);
return 0;
}
```
运行结果如下:
```
关键词 频率 编码
c 2 000
b 5 001
d 4 010
a 7 11
e 8 10
```
阅读全文