编写一个程序,实现哈夫曼编码的主要功能。程序应该能够读取一组字符及其频率,然后构建对应的哈夫曼树,生成每个字符的哈夫曼编码,并能够使用这些编码对文本进行编码和解码。
输入:
第一行包含一个整数N,表示字符的数量。
接下来的N行,每行包含一个字符和一个整数,分别表示字符和该字符的频率。
输出:
对于每个输入的字符,输出其哈夫曼编码。
最后,输出使用哈夫曼编码对输入字符进行编码后的二进制字符串。
示例:
输入:
4
A 5
B 9
C 12
D 13
输出:
A: 1111
B: 110
C: 10
D: 0
编码后的字符串: 0110111110110
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_TREE_HEIGHT 100
typedef struct HuffmanNode {
char ch;
int freq;
struct HuffmanNode *left, *right;
} HuffmanNode;
typedef struct {
HuffmanNode *root;
char codes[MAX_TREE_HEIGHT];
int codeIndex;
} HuffmanTree;
HuffmanNode* newNode(char ch, int freq) {
HuffmanNode* temp = (HuffmanNode*)malloc(sizeof(HuffmanNode));
temp->left = temp->right = NULL;
temp->ch = ch;
temp->freq = freq;
return temp;
}
int compare(const void *a, const void *b) {
HuffmanNode *nodeA = *(HuffmanNode **)a;
HuffmanNode *nodeB = *(HuffmanNode **)b;
return (nodeA->freq - nodeB->freq);
}
HuffmanTree* buildHuffmanTree(char *chars[], int freqs[], int size) {
HuffmanNode **minHeap = (HuffmanNode **)malloc(size * sizeof(HuffmanNode *));
for (int i = 0; i < size; ++i) {
minHeap[i] = newNode(chars[i], freqs[i]);
}
qsort(minHeap, size, sizeof(HuffmanNode *), compare);
while (size > 1) {
HuffmanNode *left = minHeap[0];
HuffmanNode *right = minHeap[1];
HuffmanNode *top = newNode('$', left->freq + right->freq);
top->left = left;
top->right = right;
minHeap[0] = top;
memmove(minHeap + 1, minHeap + 2, (size - 2) * sizeof(HuffmanNode *));
qsort(minHeap, size - 1, sizeof(HuffmanNode *), compare);
--size;
}
HuffmanTree *huffmanTree = (HuffmanTree*)malloc(sizeof(HuffmanTree));
huffmanTree->root = minHeap[0];
huffmanTree->codeIndex = 0;
return huffmanTree;
}
void generateHuffmanCodes(HuffmanNode *root, HuffmanTree *huffmanTree, int isLeft) {
if (!root) return;
if (root->ch != '$') {
printf("%c: ", root->ch);
for (int i = 0; i < huffmanTree->codeIndex; ++i) {
printf("%d", huffmanTree->codes[i]);
}
printf("\n");
}
huffmanTree->codes[huffmanTree->codeIndex++] = isLeft;
generateHuffmanCodes(root->left, huffmanTree, 1);
huffmanTree->codeIndex--;
generateHuffmanCodes(root->right, huffmanTree, 0);
}
char* encodeText(HuffmanTree *huffmanTree, char *text) {
HuffmanNode *current = huffmanTree->root;
char *encodedText = (char*)malloc(strlen(text) * MAX_TREE_HEIGHT + 1);
int encodedIndex = 0;
for (int i = 0; text[i] != '\0'; ++i) {
huffmanTree->codeIndex = 0;
current = huffmanTree->root;
while (current->left && current->right) {
if (current->left->ch == text[i]) {
encodedText[encodedIndex++] = '1';
current = current->left;
} else {
encodedText[encodedIndex++] = '0';
current = current->right;
}
}
}