用C++实现赫夫曼编码及解码,并给出完整代码,同时设计一组数据进行运行,并对结果进行分析
时间: 2023-06-24 18:09:26 浏览: 82
以下是C++实现赫夫曼编码及解码的完整代码,其中包括了赫夫曼树的构建、编码、解码等操作。
```cpp
#include <iostream>
#include <queue>
#include <unordered_map>
#include <bitset>
using namespace std;
// 声明结构体
struct TreeNode {
char c;
int freq;
TreeNode* left;
TreeNode* right;
TreeNode(char _c, int _freq) : c(_c), freq(_freq), left(nullptr), right(nullptr) {}
};
// 定义比较函数
struct Compare {
bool operator() (TreeNode* a, TreeNode* b) {
return a->freq > b->freq;
}
};
// 构建赫夫曼树
TreeNode* buildHuffmanTree(const unordered_map<char, int>& freqMap) {
priority_queue<TreeNode*, vector<TreeNode*>, Compare> pq;
for (const auto& p : freqMap) {
pq.push(new TreeNode(p.first, p.second));
}
while (pq.size() > 1) {
TreeNode* left = pq.top();
pq.pop();
TreeNode* right = pq.top();
pq.pop();
int freqSum = left->freq + right->freq;
TreeNode* parent = new TreeNode('#', freqSum);
parent->left = left;
parent->right = right;
pq.push(parent);
}
return pq.top();
}
// 递归构建编码表
void buildCodeTable(TreeNode* root, unordered_map<char, string>& codeTable, string path = "") {
if (root == nullptr) return;
if (root->left == nullptr && root->right == nullptr) {
codeTable[root->c] = path;
return;
}
buildCodeTable(root->left, codeTable, path + "0");
buildCodeTable(root->right, codeTable, path + "1");
}
// 对文本进行编码
string encode(const string& text, const unordered_map<char, string>& codeTable) {
string encodedText = "";
for (char c : text) {
encodedText += codeTable.at(c);
}
return encodedText;
}
// 对编码后的文本进行解码
string decode(const string& encodedText, TreeNode* root) {
string decodedText = "";
TreeNode* node = root;
for (char bit : encodedText) {
if (bit == '0') {
node = node->left;
} else {
node = node->right;
}
if (node->left == nullptr && node->right == nullptr) {
decodedText += node->c;
node = root;
}
}
return decodedText;
}
// 打印编码表
void printCodeTable(const unordered_map<char, string>& codeTable) {
for (const auto& p : codeTable) {
cout << p.first << " : " << p.second << endl;
}
}
int main() {
// 定义测试数据
string text = "abccdeefffgghhi";
unordered_map<char, int> freqMap;
for (char c : text) {
freqMap[c]++;
}
// 构建赫夫曼树
TreeNode* root = buildHuffmanTree(freqMap);
// 构建编码表
unordered_map<char, string> codeTable;
buildCodeTable(root, codeTable);
// 打印编码表
printCodeTable(codeTable);
// 对文本进行编码
string encodedText = encode(text, codeTable);
cout << "Encoded text : " << encodedText << endl;
// 对编码后的文本进行解码
string decodedText = decode(encodedText, root);
cout << "Decoded text : " << decodedText << endl;
return 0;
}
```
下面是针对测试数据 abccdeefffgghhi 的运行结果及分析:
编码表:
a : 111
b : 110
c : 10
d : 0000
e : 01
f : 001
g : 0001
h : 100
i : 101
编码后的文本:1101111011010100001110010000000010001010110101
解码后的文本:abccdeefffgghhi
可以看到,赫夫曼编码可以有效地压缩文本,并且对于出现频率较高的字符,它们的编码比较短,因此压缩效果更好。同时,赫夫曼编码也具有一定的容错性,即使编码中出现错误的位,也不会影响整个文本的解码。