用C++完成输入n个叶子结点的权值构造哈夫曼树;根据哈夫曼树构造哈夫曼编码,并对密文完成解码工作
时间: 2023-07-08 16:51:31 浏览: 147
好的,以下是用C++实现输入n个叶子节点的权值构造哈夫曼树,并根据哈夫曼树构造哈夫曼编码,最后对密文进行解码的代码:
```c++
#include <iostream>
#include <queue>
#include <string>
#include <unordered_map>
using namespace std;
// 哈夫曼树节点
struct HuffmanNode {
int val; // 权值
char ch; // 叶子节点的字符
HuffmanNode *left, *right; // 左右子节点
HuffmanNode(int val, char ch = '\0', HuffmanNode *left = nullptr, HuffmanNode *right = nullptr) :
val(val), ch(ch), left(left), right(right) {}
};
// 哈夫曼编码表
unordered_map<char, string> huffmanCode;
// 构造哈夫曼树
HuffmanNode* buildHuffmanTree(vector<int>& weights) {
auto cmp = [](HuffmanNode* a, HuffmanNode* b) {
return a->val > b->val;
};
priority_queue<HuffmanNode*, vector<HuffmanNode*>, decltype(cmp)> pq(cmp);
for (int i = 0; i < weights.size(); ++i) {
pq.push(new HuffmanNode(weights[i], (char)('A' + i)));
}
while (pq.size() > 1) {
auto left = pq.top(); pq.pop();
auto right = pq.top(); pq.pop();
auto parent = new HuffmanNode(left->val + right->val, '\0', left, right);
pq.push(parent);
}
return pq.top();
}
// 构造哈夫曼编码
void buildHuffmanCode(HuffmanNode* root, string code) {
if (!root) return;
if (root->ch != '\0') {
huffmanCode[root->ch] = code;
}
buildHuffmanCode(root->left, code + '0');
buildHuffmanCode(root->right, code + '1');
}
// 压缩数据
string compress(string data) {
string compressed;
for (char ch : data) {
compressed += huffmanCode[ch];
}
return compressed;
}
// 解压缩数据
string decompress(string compressed, HuffmanNode* root) {
string decompressed;
auto curr = root;
for (char ch : compressed) {
if (ch == '0') {
curr = curr->left;
} else {
curr = curr->right;
}
if (curr->ch != '\0') {
decompressed += curr->ch;
curr = root;
}
}
return decompressed;
}
int main() {
int n;
cout << "请输入叶子节点的个数n:" << endl;
cin >> n;
vector<int> weights(n);
cout << "请输入n个叶子节点的权值:" << endl;
for (int i = 0; i < n; ++i) {
cin >> weights[i];
}
HuffmanNode* root = buildHuffmanTree(weights);
buildHuffmanCode(root, "");
string data;
cout << "请输入需要压缩的数据:" << endl;
cin >> data;
string compressed = compress(data);
cout << "压缩后的数据:" << compressed << endl;
string decompressed = decompress(compressed, root);
cout << "解压缩后的数据:" << decompressed << endl;
return 0;
}
```
注意,此代码中将输入的叶子节点的字符默认为'A'到'A'+n-1,如果需要输入其他字符,可以修改代码。另外,此代码中没有对输入数据进行错误处理,如果输入数据不符合要求,程序可能会出错。
阅读全文