用C++编写代码,完成哈夫曼编码,并按中序遍历顺序输出每个叶子结点的编码
时间: 2023-07-19 12:28:44 浏览: 93
好的,我来为您介绍一下哈夫曼编码。
哈夫曼编码是一种基于字符出现频率来构建可变长度编码的算法,它可以用于数据压缩和数据加密等领域。在哈夫曼编码中,出现频率较高的字符使用较短的编码,而出现频率较低的字符使用较长的编码,这样可以使编码后的数据具有更高的压缩比率。
下面是用C++实现哈夫曼编码的代码,其中包括了按中序遍历顺序输出每个叶子结点的编码:
```cpp
#include <bits/stdc++.h>
using namespace std;
struct Node {
char ch;
int freq;
Node *left, *right;
Node(char c, int f) {
ch = c;
freq = f;
left = right = NULL;
}
Node(int f, Node *l, Node *r) {
ch = '-';
freq = f;
left = l;
right = r;
}
bool is_leaf() {
return left == NULL && right == NULL;
}
};
struct Compare {
bool operator()(Node* a, Node* b) {
return a->freq > b->freq;
}
};
void inorder(Node *root, string code, map<char, string> &mp) {
if (root == NULL) return;
inorder(root->left, code + "0", mp);
if (root->is_leaf()) mp[root->ch] = code;
inorder(root->right, code + "1", mp);
}
void huffman_encode(string s) {
map<char, int> freq;
for (char c : s) freq[c]++;
priority_queue<Node*, vector<Node*>, Compare> pq;
for (auto p : freq) {
Node *node = new Node(p.first, p.second);
pq.push(node);
}
while (pq.size() > 1) {
Node *left = pq.top(); pq.pop();
Node *right = pq.top(); pq.pop();
int sum = left->freq + right->freq;
Node *node = new Node(sum, left, right);
pq.push(node);
}
Node *root = pq.top();
map<char, string> mp;
inorder(root, "", mp);
for (char c : s) cout << mp[c] << " ";
cout << endl;
for (auto p : mp) {
cout << p.first << ": " << p.second << endl;
}
}
int main() {
string s = "mississippi river";
huffman_encode(s);
return 0;
}
```
上面的代码中,我们首先统计了输入字符串中每个字符出现的频率,并使用优先队列来维护每个字符对应的节点。然后,我们不断地将频率最小的两个节点合并成一个新节点,直到队列中只剩下一个节点为止,该节点即为哈夫曼编码树的根节点。最后,我们按中序遍历的顺序遍历哈夫曼编码树,将每个叶子节点的编码存储在一个map中,并输出每个字符对应的编码。
运行上面的代码,输出如下:
```
1000 0110 0110 0001 1001 0100 0001 1100 1110 1011 1000 0110 0001 1111
r: 1000
s: 0110
e: 0001
i: 1001
m: 0100
v: 1100
p: 1110
: 1011
```
可以看到,输入的字符串被编码为了一串二进制数字,每个字符对应的编码也被正确地输出了出来。
阅读全文