基于贪心法求解哈夫曼编码,写出伪代码及源码,用C++
时间: 2023-07-19 17:03:30 浏览: 274
伪代码:
1. 统计每个字符出现的频率,并将其存储在一个数组中
2. 将所有字符的频率按照从小到大的顺序排序
3. 创建一个哈夫曼树,将排好序的频率数组作为树的叶子节点,并将它们加入到一个优先队列中
4. 从优先队列中取出两个频率最小的节点,合并成一个新的节点,并计算出新节点的频率(即两个节点的频率之和)
5. 将新节点加入到哈夫曼树中
6. 重复步骤4和5,直到优先队列中只剩下一个节点(即根节点)
7. 遍历哈夫曼树,生成每个字符的编码(左子树为0,右子树为1)
C++代码实现:
```cpp
#include <iostream>
#include <queue>
#include <vector>
#include <string>
#include <map>
using namespace std;
// 定义哈夫曼树节点结构体
struct TreeNode {
char ch;
int freq;
TreeNode* left;
TreeNode* right;
TreeNode(char c, int f): ch(c), freq(f), left(nullptr), right(nullptr) {}
};
// 定义比较函数,用于优先队列的排序
struct Compare {
bool operator() (TreeNode* a, TreeNode* b) {
return a->freq > b->freq;
}
};
// 哈夫曼编码函数
map<char, string> huffmanEncoding(string text) {
// 统计字符频率
map<char, int> freqMap;
for (char c : text) {
freqMap[c]++;
}
// 将字符频率按从小到大的顺序排序
priority_queue<TreeNode*, vector<TreeNode*>, Compare> pq;
for (auto it : freqMap) {
pq.push(new TreeNode(it.first, it.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('\0', freqSum);
parent->left = left;
parent->right = right;
pq.push(parent);
}
TreeNode* root = pq.top();
// 生成哈夫曼编码
map<char, string> encodingMap;
string path;
generateEncoding(root, path, encodingMap);
// 释放内存
deleteTree(root);
return encodingMap;
}
// 生成哈夫曼编码的辅助函数
void generateEncoding(TreeNode* node, string path, map<char, string>& encodingMap) {
if (!node) return;
if (!node->left && !node->right) {
encodingMap[node->ch] = path;
return;
}
generateEncoding(node->left, path + "0", encodingMap);
generateEncoding(node->right, path + "1", encodingMap);
}
// 释放哈夫曼树的内存
void deleteTree(TreeNode* node) {
if (!node) return;
deleteTree(node->left);
deleteTree(node->right);
delete node;
}
// 测试
int main() {
string text = "hello world";
map<char, string> encodingMap = huffmanEncoding(text);
cout << "Huffman encoding for \"" << text << "\":\n";
for (auto it : encodingMap) {
cout << it.first << ": " << it.second << endl;
}
return 0;
}
```
阅读全文