霍夫曼树(Huffman Tree)是一种用于数据压缩的树形数据结构,常用于数据编码和解码。它是一种最优的前缀编码树,通过根据字符出现频率构建一棵树,将出现频率高的字符编码为较短的位数,出现频率低的字符编码为较长的位数,从而实现数据压缩。
以下是一个简单的C++实现霍夫曼树的示例:
#include <iostream>
#include <queue>
#include <vector>
class HuffmanNode {
public:
char data;
int frequency;
HuffmanNode* left;
HuffmanNode* right;
HuffmanNode(char d, int freq) : data(d), frequency(freq), left(nullptr), right(nullptr) {}
// 用于优先队列的比较函数
bool operator<(const HuffmanNode& other) const {
return frequency > other.frequency; // 优先队列按照频率从小到大排列
}
};
class HuffmanTree {
private:
HuffmanNode* root;
// 递归删除节点
void deleteNodes(HuffmanNode* node) {
if (node) {
deleteNodes(node->left);
deleteNodes(node->right);
delete node;
}
}
public:
HuffmanTree() : root(nullptr) {}
// 构建霍夫曼树
void buildTree(const std::vector<int>& frequencies) {
std::priority_queue<HuffmanNode> pq;
for (int i = 0; i < frequencies.size(); ++i) {
if (frequencies[i] > 0) {
pq.push(HuffmanNode(static_cast<char>(i), frequencies[i]));
}
}
while (pq.size() > 1) {
HuffmanNode* left = new HuffmanNode(0, 0);
*left = pq.top();
pq.pop();
HuffmanNode* right = new HuffmanNode(0, 0);
*right = pq.top();
pq.pop();
HuffmanNode* newNode = new HuffmanNode(0, left->frequency + right->frequency);
newNode->left = left;
newNode->right = right;
pq.push(*newNode);
}
if (!pq.empty()) {
root = new HuffmanNode(0, pq.top().frequency);
*root = pq.top();
}
}
// 递归打印霍夫曼树
void printTreeHelper(HuffmanNode* node, std::string code) {
if (node) {
if (!node->left && !node->right) {
std::cout << node->data << ": " << code << std::endl;
}
printTreeHelper(node->left, code + "0");
printTreeHelper(node->right, code + "1");
}
}
// 打印霍夫曼树
void printTree() {
if (root) {
printTreeHelper(root, "");
}
}
// 析构函数
~HuffmanTree() {
deleteNodes(root);
}
};
int main() {
std::vector<int> frequencies(256, 0); // ASCII字符集共有256个字符
frequencies['a'] = 5;
frequencies['b'] = 9;
frequencies['c'] = 12;
frequencies['d'] = 13;
frequencies['e'] = 16;
frequencies['f'] = 45;
HuffmanTree huffmanTree;
huffmanTree.buildTree(frequencies);
std::cout << "Huffman Tree:" << std::endl;
huffmanTree.printTree();
return 0;
}
在这个示例中,HuffmanNode 类表示霍夫曼树中的节点,包含了一个字符属性和一个频率属性,以及左右子节点的指针。HuffmanTree 类表示霍夫曼树本身,包含了一个指向根节点的指针。buildTree() 方法用于根据给定的字符频率构建霍夫曼树,printTree() 方法用于打印霍夫曼树的每个字符的编码。