用C语言编写一段程序来建立频度链表来统计字符的频度,从高到低输出各个字符频度,利用该频度链表,建立相应的哈夫曼树,并得到相应的哈夫曼编码。
时间: 2024-05-15 09:14:12 浏览: 141
以下是用C语言实现的频度链表、哈夫曼树和哈夫曼编码的代码:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_CHAR 256
// 频度链表节点
typedef struct freq_node {
char c; // 字符
int freq; // 频度
struct freq_node *next;
} freq_node_t;
// 哈夫曼树节点
typedef struct huffman_node {
char c; // 字符
int freq; // 频度
struct huffman_node *left;
struct huffman_node *right;
} huffman_node_t;
// 哈夫曼编码节点
typedef struct huffman_code {
char c; // 字符
char code[MAX_CHAR];
} huffman_code_t;
// 创建频度链表
freq_node_t *create_freq_list(char *str) {
freq_node_t *list = NULL;
freq_node_t *cur = NULL;
int freq[MAX_CHAR] = {0};
int len = strlen(str);
// 统计字符频度
for (int i = 0; i < len; i++) {
freq[(int)str[i]]++;
}
// 创建频度链表
for (int i = 0; i < MAX_CHAR; i++) {
if (freq[i] > 0) {
freq_node_t *node = (freq_node_t *)malloc(sizeof(freq_node_t));
node->c = (char)i;
node->freq = freq[i];
node->next = NULL;
if (!list) {
list = node;
} else {
cur->next = node;
}
cur = node;
}
}
return list;
}
// 打印频度链表
void print_freq_list(freq_node_t *list) {
printf("Frequency List:\n");
printf("---------------\n");
while (list) {
printf("%c: %d\n", list->c, list->freq);
list = list->next;
}
printf("\n");
}
// 插入节点到频度链表中
freq_node_t *insert_freq_node(freq_node_t *list, freq_node_t *node) {
if (!list) {
list = node;
} else if (node->freq >= list->freq) {
node->next = list;
list = node;
} else {
freq_node_t *cur = list;
while (cur->next && node->freq < cur->next->freq) {
cur = cur->next;
}
node->next = cur->next;
cur->next = node;
}
return list;
}
// 构建哈夫曼树
huffman_node_t *build_huffman_tree(freq_node_t *list) {
huffman_node_t *root = NULL;
while (list && list->next) {
freq_node_t *node1 = list;
freq_node_t *node2 = list->next;
list = list->next->next;
// 创建新节点
huffman_node_t *new_node = (huffman_node_t *)malloc(sizeof(huffman_node_t));
new_node->c = '\0';
new_node->freq = node1->freq + node2->freq;
new_node->left = (huffman_node_t *)node1;
new_node->right = (huffman_node_t *)node2;
// 插入到链表中
list = insert_freq_node(list, (freq_node_t *)new_node);
root = new_node;
}
return root;
}
// 递归生成哈夫曼编码
void generate_huffman_code(huffman_node_t *node, char *code, int depth, huffman_code_t *huffman_codes) {
if (node->left) {
code[depth] = '0';
generate_huffman_code(node->left, code, depth + 1, huffman_codes);
}
if (node->right) {
code[depth] = '1';
generate_huffman_code(node->right, code, depth + 1, huffman_codes);
}
if (!node->left && !node->right) {
// 找到叶子节点,生成哈夫曼编码
huffman_code_t *huffman_code = &huffman_codes[(int)node->c];
huffman_code->c = node->c;
strncpy(huffman_code->code, code, depth);
huffman_code->code[depth] = '\0';
}
}
// 生成哈夫曼编码
void build_huffman_code(huffman_node_t *root, huffman_code_t *huffman_codes) {
char code[MAX_CHAR] = {0};
generate_huffman_code(root, code, 0, huffman_codes);
}
// 打印哈夫曼编码
void print_huffman_code(huffman_code_t *huffman_codes) {
printf("Huffman Code:\n");
printf("-------------\n");
for (int i = 0; i < MAX_CHAR; i++) {
if (huffman_codes[i].c) {
printf("%c: %s\n", huffman_codes[i].c, huffman_codes[i].code);
}
}
printf("\n");
}
int main() {
char str[] = "hello world";
freq_node_t *freq_list = create_freq_list(str);
print_freq_list(freq_list);
huffman_node_t *root = build_huffman_tree(freq_list);
huffman_code_t huffman_codes[MAX_CHAR] = {0};
build_huffman_code(root, huffman_codes);
print_huffman_code(huffman_codes);
return 0;
}
```
该程序首先创建频度链表,统计每个字符在字符串中出现的频率,并按频率从高到低排序。然后根据频度链表构建哈夫曼树,再递归生成哈夫曼编码。最后打印出频度链表和哈夫曼编码两个结果。
阅读全文