用c语言根据字符频率构造哈夫曼树,并给出每个字符的哈夫曼编码。
时间: 2023-07-08 10:15:59 浏览: 172
哈夫曼树的c语言实现
5星 · 资源好评率100%
好的,下面是使用C语言实现哈夫曼编码的代码:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_TREE_HT 1000
// 哈夫曼树节点
struct huffman_node {
char data;
unsigned freq;
struct huffman_node *left, *right;
};
// 哈夫曼编码表
struct huffman_code {
char data;
char *code;
};
// 创建哈夫曼树节点
struct huffman_node *create_node(char data, unsigned freq) {
struct huffman_node *node = malloc(sizeof(struct huffman_node));
node->data = data;
node->freq = freq;
node->left = NULL;
node->right = NULL;
return node;
}
// 构造哈夫曼树
struct huffman_node *build_huffman_tree(char *data, unsigned *freq, int size) {
struct huffman_node *left, *right, *top;
struct huffman_node *nodes[MAX_TREE_HT];
int num_nodes = size;
int i, j;
// 初始化哈夫曼树节点数组
for (i = 0; i < num_nodes; i++) {
nodes[i] = create_node(data[i], freq[i]);
}
// 构造哈夫曼树
for (i = 1; i < num_nodes; i++) {
// 选择两个频率最小的节点
for (j = 0; j < num_nodes - i; j++) {
if (nodes[j]->freq > nodes[j+1]->freq) {
struct huffman_node *temp = nodes[j];
nodes[j] = nodes[j+1];
nodes[j+1] = temp;
}
}
left = nodes[0];
right = nodes[1];
top = create_node('$', left->freq + right->freq);
top->left = left;
top->right = right;
// 将新节点插入数组中
nodes[0] = top;
for (j = 1; j < num_nodes - i; j++) {
nodes[j] = nodes[j+1];
}
}
return nodes[0];
}
// 生成哈夫曼编码
void generate_huffman_code(struct huffman_node *root, char *code, int depth, struct huffman_code *huffman_codes) {
if (root == NULL) {
return;
}
if (root->left == NULL && root->right == NULL) {
// 叶子节点,保存编码
int index = root->data;
huffman_codes[index].data = root->data;
huffman_codes[index].code = malloc(depth + 1);
strcpy(huffman_codes[index].code, code);
return;
}
// 左子树编码为0,右子树编码为1
code[depth] = '0';
generate_huffman_code(root->left, code, depth+1, huffman_codes);
code[depth] = '1';
generate_huffman_code(root->right, code, depth+1, huffman_codes);
}
int main() {
FILE *fp;
char filename[] = "your_filename.txt";
char *content;
int freq[256] = {0};
int i;
// 打开文件
fp = fopen(filename, "r");
if (fp == NULL) {
printf("无法打开文件 %s\n", filename);
exit(1);
}
// 获取文件长度
fseek(fp, 0, SEEK_END);
long length = ftell(fp);
fseek(fp, 0, SEEK_SET);
// 分配内存并读取文件内容
content = malloc(length + 1);
fread(content, 1, length, fp);
content[length] = '\0';
// 统计字符出现频率
char *ptr = content;
while (*ptr != '\0') {
freq[(unsigned char)*ptr]++;
ptr++;
}
// 构造哈夫曼树
struct huffman_node *root = build_huffman_tree(content, freq, 256);
// 生成哈夫曼编码
struct huffman_code huffman_codes[256];
char code[MAX_TREE_HT];
code[0] = '\0';
generate_huffman_code(root, code, 0, huffman_codes);
// 打印哈夫曼编码
for (i = 0; i < 256; i++) {
if (huffman_codes[i].code != NULL) {
printf("%c: %s\n", huffman_codes[i].data, huffman_codes[i].code);
}
}
// 关闭文件并释放内存
fclose(fp);
free(content);
return 0;
}
```
请将上述代码中的 `your_filename.txt` 替换为您实际的文件名,并确保该文件存在于您的程序目录中。
该代码使用了一个结构体数组 `huffman_codes` 来存储每个字符的哈夫曼编码。程序先统计文件中每个字符的出现频率,然后根据频率构造哈夫曼树,并生成每个字符的哈夫曼编码。最后,程序遍历 `huffman_codes` 数组并打印每个字符的哈夫曼编码。
阅读全文