c++ 假设用于通信的电文仅由a,b,c,d,e,f,g,h等8个字母组成,字母在电文中出现的频率分别为0.07,0.19,0.02,0.06,0.32,0.03,0.21,0.10。试为这8个字母设计哈夫曼编码。
时间: 2024-11-29 17:35:44 浏览: 2
哈夫曼编码是一种基于频率的变长前缀编码,常用于压缩数据。对于这个问题,我们需要按照字母出现的频率构建一颗哈夫曼树,然后给每个字母分配一个最短的二进制编码。以下是创建哈夫曼树并计算编码的过程:
1. **创建频率列表**:首先,将字母及其频率存储在一个结构体数组里,如`pair<char, double>`。
```cpp
#include <string>
#include <vector>
#include <queue>
#include <map>
std::vector<std::pair<char, double>> freqs = {
{'a', 0.07}, {'b', 0.19}, {'c', 0.02}, {'d', 0.06},
{'e', 0.32}, {'f', 0.03}, {'g', 0.21}, {'h', 0.10}
};
```
2. **构建哈夫曼树**:
- 创建一个优先队列存放成对的节点(频率+字符),初始时放入所有频率对应的节点。
- 选取频率最低的两对节点合并成新的节点,新节点的频率为其子节点频率之和,并将它们排序回队列。
- 重复此过程直到只剩下一个节点,即为哈夫曼树的根节点。
```cpp
std::priority_queue<std::pair<double, std::pair<char, char>>> huffmanQueue(freqs.begin(), freqs.end());
while (huffmanQueue.size() > 1) {
auto nodeA = huffmanQueue.top(); huffmanQueue.pop();
auto nodeB = huffmanQueue.top(); huffmanQueue.pop();
huffmanQueue.push({nodeA.first + nodeB.first, {nodeA.second.first, nodeB.second.first}});
huffmanQueue.push({nodeA.first + nodeB.first, {nodeA.second.second, nodeB.second.second}});
huffmanQueue.sort();
}
auto huffmanRoot = huffmanQueue.top().second; // 根节点
```
3. **确定编码**:
- 从根节点出发,沿着路径记录下遇到的所有'0'和'1',直到到达叶节点。这个路径就是该字母的哈夫曼编码。
```cpp
std::map<char, std::string> huffmanCodes;
void buildHuffmanCode(BiTreeNode* node, std::string code, std::map<char, std::string>& codes) {
if (!node->left && !node->right) { // 叶节点,添加到映射中
huffmanCodes[node->data] = code;
} else {
buildHuffmanCode(node->left, code + "0", codes);
buildHuffmanCode(node->right, code + "1", codes);
}
}
buildHuffmanCode(huffmanRoot, "", huffmanCodes);
```
现在,`huffmanCodes`中包含了每个字母及其对应的哈夫曼编码。例如,'e'可能是最常见的字母,所以它的编码可能是最短的。
阅读全文