请用C语言实现
时间: 2024-02-09 22:09:32 浏览: 27
好的,这是一个使用C语言实现哈夫曼编码的示例代码。在这个示例中,我们将使用一个结构体来表示哈夫曼树的节点,以及一个数组来存储每个字符对应的编码。
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_TREE_HT 100
#define MAX_CHAR 256
// 哈夫曼树节点
struct node {
char data;
unsigned freq;
struct node *left, *right;
};
// 哈夫曼编码
struct code {
char c;
char bits[MAX_TREE_HT];
};
// 创建一个新的哈夫曼树节点
struct node* new_node(char data, unsigned freq) {
struct node* node = (struct node*)malloc(sizeof(struct node));
node->left = node->right = NULL;
node->data = data;
node->freq = freq;
return node;
}
// 交换两个哈夫曼树节点
void swap_node(struct node **a, struct node **b) {
struct node *tmp = *a;
*a = *b;
*b = tmp;
}
// 将哈夫曼树节点按照频率排序
void sort_node(struct node **arr, int n) {
int i, j;
for (i = 0; i < n - 1; i++) {
for (j = 0; j < n - i - 1; j++) {
if (arr[j]->freq > arr[j+1]->freq) {
swap_node(&arr[j], &arr[j+1]);
}
}
}
}
// 构建哈夫曼树
struct node* build_tree(char *data, int *freq, int n) {
struct node *left, *right, *top;
struct node *arr[MAX_CHAR];
int i, j, k;
// 将每个字符作为一个叶子节点
for (i = 0; i < n; i++) {
arr[i] = new_node(data[i], freq[i]);
}
// 直到只剩下一个节点
while (n > 1) {
// 排序节点
sort_node(arr, n);
// 取出频率最小的两个节点
left = arr[0];
right = arr[1];
// 创建一个新节点作为它们的父节点
top = new_node('$', left->freq + right->freq);
top->left = left;
top->right = right;
// 将新节点插入到数组中
arr[0] = top;
for (j = 1; j < n - 1; j++) {
arr[j] = arr[j+1];
}
n--;
}
return arr[0];
}
// 根据哈夫曼树获取每个字符的编码
void get_codes(struct node *root, char *bits, int top, struct code *codes) {
if (root->left) {
bits[top] = '0';
get_codes(root->left, bits, top+1, codes);
}
if (root->right) {
bits[top] = '1';
get_codes(root->right, bits, top+1, codes);
}
if (!root->left && !root->right) {
codes[root->data].c = root->data;
memcpy(codes[root->data].bits, bits, top);
codes[root->data].bits[top] = '\0';
}
}
// 哈夫曼编码
void huffman_encode(char *data, int *freq, int n, struct code *codes) {
struct node *root;
char bits[MAX_TREE_HT];
int top = 0;
// 构建哈夫曼树
root = build_tree(data, freq, n);
// 获取每个字符的编码
get_codes(root, bits, top, codes);
}
int main() {
char data[] = "ABBCCCDDDDEEEEE";
int freq[MAX_CHAR] = {0};
int n = strlen(data);
struct code codes[MAX_CHAR] = {0};
int i;
// 计算每个字符在电文中出现的频率
for (i = 0; i < n; i++) {
freq[data[i]]++;
}
// 哈夫曼编码
huffman_encode(data, freq, n, codes);
// 打印每个字符的编码
for (i = 0; i < MAX_CHAR; i++) {
if (codes[i].c != '\0') {
printf("'%c': %s\n", codes[i].c, codes[i].bits);
}
}
return 0;
}
```
这个示例中,我们首先计算每个字符在电文中出现的频率,然后使用`build_tree`函数构建哈夫曼树。接着,我们使用`get_codes`函数获取每个字符的编码,最后打印出每个字符的编码。