C语言实现根据电文中各字符出现的频率,建立哈夫曼树,并设计字符的哈夫曼编码。 1) 建立并输出哈夫曼树的存储结构; 2) 根据哈夫曼树,设计并输出对应字符的哈夫曼编码; 3) 将指定接收到的电文进行译码并输出。
时间: 2024-03-19 19:44:48 浏览: 63
哈夫曼树编码和译码,C语言实现
好的,以下是实现该任务的 C 代码:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <ctype.h>
#define MAX_TREE_HT 100
typedef struct HuffmanNode {
char data;
int freq;
struct HuffmanNode* left;
struct HuffmanNode* right;
} HuffmanNode;
typedef struct MinHeap {
unsigned size;
unsigned capacity;
HuffmanNode** array;
} MinHeap;
typedef struct HuffmanCode {
char data;
char* code;
} HuffmanCode;
HuffmanNode* create_node(char data, int freq, HuffmanNode* left, HuffmanNode* right) {
HuffmanNode* node = (HuffmanNode*)malloc(sizeof(HuffmanNode));
node->data = data;
node->freq = freq;
node->left = left;
node->right = right;
return node;
}
MinHeap* create_min_heap(unsigned capacity) {
MinHeap* min_heap = (MinHeap*)malloc(sizeof(MinHeap));
min_heap->size = 0;
min_heap->capacity = capacity;
min_heap->array = (HuffmanNode**)malloc(capacity * sizeof(HuffmanNode*));
return min_heap;
}
void swap_nodes(HuffmanNode** a, HuffmanNode** b) {
HuffmanNode* temp = *a;
*a = *b;
*b = temp;
}
void min_heapify(MinHeap* min_heap, int idx) {
int smallest = idx;
int left = 2 * idx + 1;
int right = 2 * idx + 2;
if (left < min_heap->size && min_heap->array[left]->freq < min_heap->array[smallest]->freq) {
smallest = left;
}
if (right < min_heap->size && min_heap->array[right]->freq < min_heap->array[smallest]->freq) {
smallest = right;
}
if (smallest != idx) {
swap_nodes(&min_heap->array[smallest], &min_heap->array[idx]);
min_heapify(min_heap, smallest);
}
}
bool is_size_one(MinHeap* min_heap) {
return min_heap->size == 1;
}
HuffmanNode* extract_min(MinHeap* min_heap) {
HuffmanNode* temp = min_heap->array[0];
min_heap->array[0] = min_heap->array[min_heap->size - 1];
--min_heap->size;
min_heapify(min_heap, 0);
return temp;
}
void insert_min_heap(MinHeap* min_heap, HuffmanNode* node) {
++min_heap->size;
int i = min_heap->size - 1;
while (i && node->freq < min_heap->array[(i - 1) / 2]->freq) {
min_heap->array[i] = min_heap->array[(i - 1) / 2];
i = (i - 1) / 2;
}
min_heap->array[i] = node;
}
void build_min_heap(MinHeap* min_heap) {
int n = min_heap->size - 1;
int i;
for (i = (n - 1) / 2; i >= 0; --i) {
min_heapify(min_heap, i);
}
}
void print_huffman_tree(HuffmanNode* root, int level) {
if (root) {
int i;
for (i = 0; i < level; ++i) {
printf("\t");
}
if (root->data) {
printf("(%c, %d)\n", root->data, root->freq);
} else {
printf("(%d)\n", root->freq);
}
print_huffman_tree(root->left, level + 1);
print_huffman_tree(root->right, level + 1);
}
}
void build_and_print_huffman_tree(char* text, int n) {
int freq[256] = {0};
int i;
for (i = 0; i < n; ++i) {
++freq[text[i]];
}
MinHeap* min_heap = create_min_heap(256);
for (i = 0; i < 256; ++i) {
if (freq[i]) {
insert_min_heap(min_heap, create_node(i, freq[i], NULL, NULL));
}
}
build_min_heap(min_heap);
while (!is_size_one(min_heap)) {
HuffmanNode* left = extract_min(min_heap);
HuffmanNode* right = extract_min(min_heap);
HuffmanNode* parent = create_node('$', left->freq + right->freq, left, right);
insert_min_heap(min_heap, parent);
}
HuffmanNode* root = min_heap->array[0];
printf("Huffman Tree:\n");
print_huffman_tree(root, 0);
}
void build_huffman_codes(HuffmanNode* root, char* code, int top, HuffmanCode* codes) {
if (root->left) {
code[top] = '0';
build_huffman_codes(root->left, code, top + 1, codes);
}
if (root->right) {
code[top] = '1';
build_huffman_codes(root->right, code, top + 1, codes);
}
if (!root->left && !root->right) {
codes[root->data].data = root->data;
codes[root->data].code = (char*)malloc((top + 1) * sizeof(char));
strncpy(codes[root->data].code, code, top);
codes[root->data].code[top] = '\0';
}
}
void print_huffman_codes(HuffmanCode* codes) {
printf("Huffman Codes:\n");
int i;
for (i = 0; i < 256; ++i) {
if (codes[i].code) {
printf("%c: %s\n", codes[i].data, codes[i].code);
}
}
}
void encode_text(char* text, int n, HuffmanCode* codes, char* encoded_text) {
int i;
for (i = 0; i < n; ++i) {
strcat(encoded_text, codes[text[i]].code);
}
}
void decode_text(char* encoded_text, int n, HuffmanNode* root, char* decoded_text) {
int i;
HuffmanNode* current = root;
for (i = 0; i < n; ++i) {
if (encoded_text[i] == '0') {
current = current->left;
} else {
current = current->right;
}
if (!current->left && !current->right) {
decoded_text[strlen(decoded_text)] = current->data;
current = root;
}
}
}
int main() {
char text[] = "hello world";
int n = strlen(text);
build_and_print_huffman_tree(text, n);
HuffmanCode codes[256] = {0};
char code[MAX_TREE_HT] = {0};
build_huffman_codes(create_node('$', 0, NULL, NULL), code, 0, codes);
print_huffman_codes(codes);
char encoded_text[MAX_TREE_HT * n] = {0};
encode_text(text, n, codes, encoded_text);
printf("Encoded Text: %s\n", encoded_text);
char decoded_text[MAX_TREE_HT * n] = {0};
decode_text(encoded_text, strlen(encoded_text), create_node('$', 0, NULL, NULL), decoded_text);
printf("Decoded Text: %s\n", decoded_text);
return 0;
}
```
这段代码实现了建立哈夫曼树、设计字符的哈夫曼编码、对指定接收到的电文进行译码功能。你可以根据需求自行修改代码。
阅读全文