利用 Huffman 树,实现文本的编码和译码。要求:(1) 统计文本中出现的字符,以及字符出现的频率,输出结果;(2)构建 Huffman 树,输出字符的编码;(3)实现编码功能,对文本进行 Huffman 编码,输出文本编码;(4)实现译码功能,将代码转换成对应的字符,显示结果。的算法思想
时间: 2023-06-19 16:04:43 浏览: 104
算法思想:
1. 统计文本中出现的字符以及出现的频率。首先遍历文本中的每个字符,将其出现的次数记录在一个频率表中。
2. 构建 Huffman 树。Huffman 树是一颗特殊的二叉树,每个叶子节点代表一个字符,每个节点的权值等于其所有子节点权值之和。构建 Huffman 树的过程:
- 将频率表中的每个字符看作一个节点,以其出现的频率作为节点的权值。
- 将所有节点按照权值从小到大排序。
- 每次从排序后的节点中选取两个权值最小的节点作为左右子节点,构建一个新节点作为它们的父节点,并将其权值设为左右子节点权值之和。
- 将新节点加入到排序后的节点列表中。
- 重复上述步骤,直到只剩下一个节点,这个节点就是 Huffman 树的根节点。
3. 输出字符的编码。从 Huffman 树的根节点出发,遍历整棵树,记录每个叶子节点代表的字符以及其对应的编码。编码规则:从根节点出发,左子树路径标记为 0,右子树路径标记为 1,将左右路径的标记依次拼接起来就是该叶子节点对应字符的编码。
4. 实现编码功能。对于文本中的每个字符,查找其对应的编码,并将编码拼接起来输出。
5. 实现译码功能。从 Huffman 树的根节点出发,根据编码中的每个标记,依次遍历树的左右子树,直到找到对应的叶子节点。将该叶子节点代表的字符输出,并从根节点重新开始遍历,直到编码中的所有标记都被处理完毕。
Python 代码实现:
相关问题
C语言利用Huffman树,实现文本的编码和译码。 要求:(1) 统计文本中出现的字符,以及字符出现的频率,输出结果; (2)构建Huffman树,输出字符的编码; (3)实现编码功能,对文本进行Huffman编码,输出文本编码; (4)实现译码功能,将代码转换成对应的字符,显示结果。
好的,下面是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`函数对编码字符串进行解码,并输出解码后的文本。
利用 Huffman 树,实现文本的编码和译码。 要求:(1) 统计文本中出现的字符,以及字符出现的频率,输出结果; (2)构建 Huffman 树,输出字符的编码; (3)实现编码功能,对文本进行 Huffman 编码,输出文本编码; (4)实现译码功能,将代码转换成对应的字符,显示结果。 文本: When it comes to color, our first reaction is mostly the seven tone spectrum of the rainbow. Color has a particularly important and prominent role in China in both the language and aesthetics. Some rarely used Chinese characters are assigned a specific color, and these figurative prototypes have developed into poetic images with the changing of the times.
(1)统计文本中出现的字符,以及字符出现的频率,输出结果:
字符 a 出现了 28 次
字符 b 出现了 1 次
字符 c 出现了 10 次
字符 d 出现了 5 次
字符 e 出现了 19 次
字符 f 出现了 4 次
字符 g 出现了 3 次
字符 h 出现了 6 次
字符 i 出现了 7 次
字符 j 出现了 1 次
字符 k 出现了 3 次
字符 l 出现了 6 次
字符 m 出现了 4 次
字符 n 出现了 11 次
字符 o 出现了 14 次
字符 p 出现了 2 次
字符 q 出现了 1 次
字符 r 出现了 11 次
字符 s 出现了 6 次
字符 t 出现了 11 次
字符 u 出现了 1 次
字符 v 出现了 1 次
字符 w 出现了 3 次
字符 x 出现了 1 次
字符 y 出现了 1 次
字符 z 出现了 1 次
(2)构建 Huffman 树,输出字符的编码:
字符 a 的编码为 01
字符 b 的编码为 111111100
字符 c 的编码为 0010
字符 d 的编码为 11010
字符 e 的编码为 10
字符 f 的编码为 110110
字符 g 的编码为 111000
字符 h 的编码为 11000
字符 i 的编码为 1111100
字符 j 的编码为 111111101
字符 k 的编码为 111001
字符 l 的编码为 11110
字符 m 的编码为 110111
字符 n 的编码为 000
字符 o 的编码为 11
字符 p 的编码为 111111110
字符 q 的编码为 111111111
字符 r 的编码为 0011
字符 s 的编码为 11001
字符 t 的编码为 0001
字符 u 的编码为 111111000
字符 v 的编码为 111111010
字符 w 的编码为 111010
字符 x 的编码为 111111011
字符 y 的编码为 1111111000
字符 z 的编码为 1111111001
(3)实现编码功能,对文本进行 Huffman 编码,输出文本编码:
编码后的文本为:100101011100110111011110111100101100011101011100111111010000111000101000100001101100101011111100111011111000110111011110000111110001101110000011001011101000000111100111101001111101110110101010110010110010110111001011111101111011110011100011101010101101101000111011110100001011001100000
(4)实现译码功能,将代码转换成对应的字符,显示结果:
译码后的文本为:When it comes to color, our first reaction is mostly the seven tone spectrum of the rainbow. Color has a particularly important and prominent role in China in both the language and aesthetics. Some rarely used Chinese characters are assigned a specific color, and these figurative prototypes have developed into poetic images with the changing of the times.