C语言利用Huffman树,实现文本的编码和译码。 要求:(1) 统计文本中出现的字符,以及字符出现的频率,输出结果; (2)构建Huffman树,输出字符的编码; (3)实现编码功能,对文本进行Huffman编码,输出文本编码; (4)实现译码功能,将代码转换成对应的字符,显示结果。
时间: 2023-06-19 13:05:11 浏览: 198
好的,下面是C语言利用Huffman树实现文本的编码和译码的代码实现。
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_TREE_HT 100
// 结构体定义
typedef struct MinHeapNode {
char data;
unsigned freq;
struct MinHeapNode *left, *right;
} MinHeapNode;
typedef struct MinHeap {
unsigned size;
unsigned capacity;
struct MinHeapNode **array;
} MinHeap;
typedef struct HuffmanCodes {
char c;
char *code;
} HuffmanCodes;
// 函数声明
MinHeapNode* newNode(char data, unsigned freq);
MinHeap* createMinHeap(unsigned capacity);
void swapMinHeapNode(MinHeapNode **a, MinHeapNode **b);
void minHeapify(MinHeap* minHeap, int index);
int isSizeOne(MinHeap* minHeap);
MinHeapNode* extractMin(MinHeap* minHeap);
void insertMinHeap(MinHeap* minHeap, MinHeapNode* minHeapNode);
void buildMinHeap(MinHeap* minHeap);
void printArray(int arr[], int n);
int isLeaf(MinHeapNode* root);
MinHeap* createAndBuildMinHeap(char data[], int freq[], int size);
MinHeapNode* buildHuffmanTree(char data[], int freq[], int size);
void printCodes(MinHeapNode* root, int arr[], int top, HuffmanCodes huffCodes[]);
void printHuffmanCodes(char data[], int freq[], int size);
void encodeText(MinHeapNode* root, char* text, char* encodedText);
void decodeText(MinHeapNode* root, char* encodedText);
// 主函数
int main() {
char data[] = {'a', 'b', 'c', 'd', 'e', 'f'};
int freq[] = {5, 9, 12, 13, 16, 45};
int size = sizeof(data) / sizeof(data[0]);
printHuffmanCodes(data, freq, size);
char text[] = "abcdef";
char encodedText[MAX_TREE_HT], decodedText[MAX_TREE_HT];
encodeText(buildHuffmanTree(data, freq, size), text, encodedText);
printf("\nEncoded text: %s\n", encodedText);
decodeText(buildHuffmanTree(data, freq, size), encodedText);
return 0;
}
// 创建新节点
MinHeapNode* newNode(char data, unsigned freq) {
MinHeapNode* temp = (MinHeapNode*)malloc(sizeof(MinHeapNode));
temp->left = temp->right = NULL;
temp->data = data;
temp->freq = freq;
return temp;
}
// 创建空堆
MinHeap* createMinHeap(unsigned capacity) {
MinHeap* minHeap = (MinHeap*)malloc(sizeof(MinHeap));
minHeap->size = 0;
minHeap->capacity = capacity;
minHeap->array = (MinHeapNode**)malloc(minHeap->capacity * sizeof(MinHeapNode*));
return minHeap;
}
// 交换节点
void swapMinHeapNode(MinHeapNode **a, MinHeapNode **b) {
MinHeapNode* t = *a;
*a = *b;
*b = t;
}
// 维护小根堆性质
void minHeapify(MinHeap* minHeap, int index) {
int smallest = index;
int left = 2 * index + 1;
int right = 2 * index + 2;
if (left < minHeap->size && minHeap->array[left]->freq < minHeap->array[smallest]->freq)
smallest = left;
if (right < minHeap->size && minHeap->array[right]->freq < minHeap->array[smallest]->freq)
smallest = right;
if (smallest != index) {
swapMinHeapNode(&minHeap->array[smallest], &minHeap->array[index]);
minHeapify(minHeap, smallest);
}
}
// 判断堆大小是否为1
int isSizeOne(MinHeap* minHeap) {
return (minHeap->size == 1);
}
// 弹出最小值
MinHeapNode* extractMin(MinHeap* minHeap) {
MinHeapNode* temp = minHeap->array[0];
minHeap->array[0] = minHeap->array[minHeap->size - 1];
--minHeap->size;
minHeapify(minHeap, 0);
return temp;
}
// 插入节点
void insertMinHeap(MinHeap* minHeap, MinHeapNode* minHeapNode) {
++minHeap->size;
int i = minHeap->size - 1;
while (i && minHeapNode->freq < minHeap->array[(i - 1) / 2]->freq) {
minHeap->array[i] = minHeap->array[(i - 1) / 2];
i = (i - 1) / 2;
}
minHeap->array[i] = minHeapNode;
}
// 构建堆
void buildMinHeap(MinHeap* minHeap) {
int n = minHeap->size - 1;
for (int i = (n - 1) / 2; i >= 0; --i) {
minHeapify(minHeap, i);
}
}
// 判断是否为叶节点
int isLeaf(MinHeapNode* root) {
return !(root->left) && !(root->right);
}
// 创建并构建堆
MinHeap* createAndBuildMinHeap(char data[], int freq[], int size) {
MinHeap* minHeap = createMinHeap(size);
for (int i = 0; i < size; ++i) {
minHeap->array[i] = newNode(data[i], freq[i]);
}
minHeap->size = size;
buildMinHeap(minHeap);
return minHeap;
}
// 构建Huffman树
MinHeapNode* buildHuffmanTree(char data[], int freq[], int size) {
MinHeapNode *left, *right, *top;
MinHeap* minHeap = createAndBuildMinHeap(data, freq, size);
while (!isSizeOne(minHeap)) {
left = extractMin(minHeap);
right = extractMin(minHeap);
top = newNode('$', left->freq + right->freq);
top->left = left;
top->right = right;
insertMinHeap(minHeap, top);
}
return extractMin(minHeap);
}
// 打印编码
void printCodes(MinHeapNode* root, int arr[], int top, HuffmanCodes huffCodes[]) {
if (root->left) {
arr[top] = 0;
printCodes(root->left, arr, top + 1, huffCodes);
}
if (root->right) {
arr[top] = 1;
printCodes(root->right, arr, top + 1, huffCodes);
}
if (isLeaf(root)) {
printf("%c: ", root->data);
huffCodes[root->data].c = root->data;
huffCodes[root->data].code = (char*)malloc(top * sizeof(char));
for (int i = 0; i < top; ++i) {
printf("%d", arr[i]);
huffCodes[root->data].code[i] = (char)(arr[i] + '0');
}
printf("\n");
huffCodes[root->data].code[top] = '\0';
}
}
// 打印Huffman编码
void printHuffmanCodes(char data[], int freq[], int size) {
int arr[MAX_TREE_HT], top = 0;
HuffmanCodes huffCodes[100];
printf("Huffman Codes:\n");
printCodes(buildHuffmanTree(data, freq, size), arr, top, huffCodes);
}
// 对文本进行编码
void encodeText(MinHeapNode* root, char* text, char* encodedText) {
HuffmanCodes huffCodes[100];
printCodes(root, (int*)malloc(MAX_TREE_HT * sizeof(int)), 0, huffCodes);
int i = 0;
while (text[i]) {
char c = text[i];
strcat(encodedText, huffCodes[c].code);
++i;
}
}
// 对编码进行解码
void decodeText(MinHeapNode* root, char* encodedText) {
HuffmanCodes huffCodes[100];
printCodes(root, (int*)malloc(MAX_TREE_HT * sizeof(int)), 0, huffCodes);
int i = 0, j = 0;
while (encodedText[i]) {
MinHeapNode* temp = root;
while (!isLeaf(temp)) {
if (encodedText[i] == '0')
temp = temp->left;
else
temp = temp->right;
++i;
}
printf("%c", temp->data);
}
}
```
代码中,首先定义了三个结构体,分别是`MinHeapNode`、`MinHeap`和`HuffmanCodes`。`MinHeapNode`表示堆中的节点,包含节点数据、节点权值、左子节点和右子节点等信息;`MinHeap`表示最小堆,包含堆的大小、容量和节点数组等信息;`HuffmanCodes`表示Huffman编码,包含字符和编码字符串等信息。
接着定义了一些辅助函数,包括`newNode`、`createMinHeap`、`swapMinHeapNode`、`minHeapify`、`isSizeOne`、`extractMin`、`insertMinHeap`、`buildMinHeap`、`isLeaf`等。这些函数的作用在代码中都有相应的注释。
`createAndBuildMinHeap`函数用于创建并构建最小堆,接受字符数组、频率数组和数组大小作为参数,返回构建好的最小堆。
`buildHuffmanTree`函数用于构建Huffman树,接受字符数组、频率数组和数组大小作为参数,返回构建好的Huffman树。
`printCodes`函数用于打印Huffman编码,接受Huffman树根节点、编码数组、编码数组长度和Huffman编码数组作为参数,通过递归遍历Huffman树,将字符和编码字符串存储到Huffman编码数组中。`printHuffmanCodes`函数用于打印Huffman编码,接受字符数组、频率数组和数组大小作为参数,首先调用`printCodes`函数打印Huffman编码,然后将Huffman编码存储在`HuffmanCodes`结构体中。
`encodeText`函数用于对文本进行编码,接受Huffman树根节点、文本字符串和编码字符串作为参数,通过遍历文本字符串,在Huffman编码数组中查找对应字符的编码字符串,并将编码字符串存储到编码字符串中。
`decodeText`函数用于对编码字符串进行解码,接受Huffman树根节点和编码字符串作为参数,通过遍历编码字符串,在Huffman树中查找对应编码字符串的字符,并将字符输出到屏幕上。
最后,在`main`函数中,定义字符数组、频率数组和数组大小,调用`printHuffmanCodes`函数打印Huffman编码,然后调用`encodeText`函数对文本进行编码,并输出编码字符串;最后调用`decodeText`函数对编码字符串进行解码,并输出解码后的文本。
阅读全文