假定用于通信的电文由8个字母A、B、C、D、E、F、G、H组成,各字母在电文中出现的概率为5%,25%,4%,7%,9%,12%,30%,8%,试编程为这8个字母设计赫夫曼编码
时间: 2024-11-30 18:20:23 浏览: 48
为了使用赫夫曼编码对这些字母进行编码,我们需要遵循以下步骤:
1. **计算概率**: 统计每个字母出现的概率。
2. **构建哈夫曼树**: 使用这些概率值构建一颗赫夫曼树。
3. **赋予编码**: 从根节点开始,对于每个叶子节点,从左子树到右子树记录编码,通常0表示向左走,1表示向右走。
这里是一个简单的C++代码示例,实现了这个过程:
```cpp
#include <iostream>
#include <vector>
#include <queue>
#include <map>
using namespace std;
struct Node {
char ch;
double freq;
Node* l, *r;
Node(char ch, double freq) : ch(ch), freq(freq), l(NULL), r(NULL) {}
};
// 按频率升序排序
bool compare(Node* a, Node* b) {
return a->freq < b->freq;
}
// 创建新节点
Node* newNode(char ch, double freq) {
return new Node(ch, freq);
}
// 构建赫夫曼树
Node* buildHuffmanTree(vector<Node*> &nodes) {
sort(nodes.begin(), nodes.end(), compare);
while (nodes.size() > 1) {
auto it1 = nodes.begin();
advance(it1, 1); // 跳过第一个元素,它是当前的最小值
auto it2 = it1;
advance(it2, 1); // 下一个最小值
Node* root = newNode('\0', it1->freq + it2->freq);
root->l = it1;
root->r = it2;
nodes.erase(it1);
nodes.erase(it2);
nodes.push_back(root);
sort(nodes.begin(), nodes.end(), compare);
}
return nodes[0]; // 返回剩下的唯一元素,即赫夫曼树的根
}
// 计算编码
string getHuffmanCode(Node* root, string code, char ch) {
if (!root->l && !root->r) { // 如果到达叶子节点,返回编码
return code + to_string(root->ch);
}
if (root->ch == ch) { // 如果是目标字符,向右继续
return getHuffmanCode(root->r, "1" + code, ch);
} else { // 否则向左继续
return getHuffmanCode(root->l, "0" + code, ch);
}
}
int main() {
vector<Node*> alphabet = {
newNode('A', 0.05),
newNode('B', 0.25),
newNode('C', 0.04),
newNode('D', 0.07),
newNode('E', 0.09),
newNode('F', 0.12),
newNode('G', 0.30),
newNode('H', 0.08)
};
alphabet = {buildHuffmanTree(alphabet).l, buildHuffmanTree(alphabet).r}; // 合并左右子树
map<char, string> huffmanCodes;
for (auto& node : alphabet) {
huffmanCodes[node->ch] = getHuffmanCode(node, "", node->ch);
}
cout << "Huffman Codes:" << endl;
for (const auto& pair : huffmanCodes) {
cout << pair.first << ": " << pair.second << endl;
}
return 0;
}
```
这段代码将输出每个字母的赫夫曼编码。注意,实际运行此代码需要在支持指针操作的环境中,例如C++。
阅读全文