请用c++编码编写哈夫曼树给定编码的权值怎么输出
时间: 2024-12-15 22:16:10 浏览: 3
哈夫曼树是一种用于数据压缩的二叉树,其构建过程通常涉及创建一个带权路径长度(WPL,即每个节点的权重加上其左、右子树的权重)最小的二叉树。以下是使用C++基本地模拟这个过程的一个简要示例,这里假设我们有一个简单的数组表示权值,并用优先队列实现:
```cpp
#include <queue>
#include <vector>
// 权值结构体
struct Weight {
int value;
int frequency; // 权值对应的频次
};
// 比较两个权值结构的WPL
bool compareByWpl(const Weight& a, const Weight& b) {
return a.value + a.frequency * (a.frequency - 1) / 2 < b.value + b.frequency * (b.frequency - 1) / 2;
}
// 构建哈夫曼树并获取编码
std::pair<Weight, std::string> buildHuffmanTree(std::vector<Weight>& weights) {
std::priority_queue<Weight, std::vector<Weight>, decltype(compareByWpl)> pq(compareByWpl);
for (const auto& weight : weights)
pq.push(weight);
while (pq.size() > 1) {
Weight left = pq.top(); pq.pop();
Weight right = pq.top(); pq.pop();
pq.push({left.value + right.value, left.frequency + right.frequency});
pq.push(left); // 左子树压回
pq.push(right); // 右子树压回
}
Weight root = pq.top();
std::string code(root.frequency, '0'); // 初始化根节点的编码为0
std::function<void(Weight, size_t)> traverse = [&](Weight node, size_t bit) {
if (node.left == nullptr && node.right == nullptr) {
codes[node.value] = std::to_string(bit); // 如果叶子节点,记录编码
} else {
traverse(node.left, bit | 1); // 访问左子树,将当前位设为1
traverse(node.right, bit); // 访问右子树,保持当前位
}
};
traverse(root, 0);
return {root, codes};
}
// 示例权值列表,假设已经包含频率信息
std::vector<Weight> weights = {{5, 2}, {3, 4}, {7, 1}};
// 主函数测试
int main() {
auto [huffmanRoot, codes] = buildHuffmanTree(weights);
std::cout << "Huffman Tree Root: Value=" << huffmanRoot.value << ", Frequency=" << huffmanRoot.frequency << std::endl;
for (const auto& pair : codes) {
std::cout << "Value: " << pair.first << ", Code: " << codes[pair.first] << std::endl;
}
return 0;
}
```
在这个例子中,`buildHuffmanTree` 函数首先构建了一个优先队列,然后通过不断合并两个权值最小的节点形成新的节点,直到只剩下一个节点(即哈夫曼树的根)。同时,它还递归地生成了每个叶子节点的编码。
请注意这只是一个基础版本,实际应用中可能需要处理更复杂的情况,例如动态添加或删除权值,以及存储整个编码表。此外,真正的哈夫曼编码通常是通过动态分配内存和更复杂的算法实现的。
阅读全文