哈夫曼树(Huffman Tree)是一种用于编码和解码的数据结构。它是一种二叉树,具有以下特点:
- 权值越大的节点越靠近树的根部。
- 没有度为1的节点。
- 叶子节点存储着编码后的数据,而非叶子节点存储着编码规则。
哈夫曼表(Huffman Table)是用于存储字符和其对应编码的数据结构。它可以通过哈夫曼树来生成,具有以下特点:
- 每个字符都有唯一的编码。
- 编码的长度和字符的出现频率相关,频率越高的字符编码越短。
在C++中,可以使用结构体或类来实现哈夫曼树和哈夫曼表。
下面是一个使用结构体来实现哈夫曼树的示例代码:
cpp
// 哈夫曼树节点
struct HuffmanNode {
char data; // 节点存储的字符
int weight; // 节点的权值
HuffmanNode* left; // 左子节点指针
HuffmanNode* right; // 右子节点指针
HuffmanNode(char d, int w) : data(d), weight(w), left(nullptr), right(nullptr) {}
};
// 构造哈夫曼树
HuffmanNode* buildHuffmanTree(vector<pair<char, int>>& data) {
struct Compare {
bool operator()(HuffmanNode* a, HuffmanNode* b) {
return a->weight > b->weight;
}
};
priority_queue<HuffmanNode*, vector<HuffmanNode*>, Compare> pq;
// 将data中的字符和权值构造为HuffmanNode,并放入优先队列
for (auto ele : data) {
pq.push(new HuffmanNode(ele.first, ele.second));
}
// 不断取出权值最小的两个节点,构造新的节点,再放入优先队列,直到只剩下一个节点
while (pq.size() > 1) {
HuffmanNode* node1 = pq.top();
pq.pop();
HuffmanNode* node2 = pq.top();
pq.pop();
HuffmanNode* newNode = new HuffmanNode('\0', node1->weight + node2->weight);
newNode->left = node1;
newNode->right = node2;
pq.push(newNode);
}
return pq.top();
}
下面是一个使用哈夫曼树生成哈夫曼表的示例代码:
cpp
// 哈夫曼表条目
struct HuffmanEntry {
char data; // 字符
string code; // 字符对应的编码
};
// 构造哈夫曼表
void buildHuffmanTable(HuffmanNode* root, string code, vector<HuffmanEntry>& table) {
if (root == nullptr) {
return;
}
if (root->left == nullptr && root->right == nullptr) {
HuffmanEntry entry;
entry.data = root->data;
entry.code = code;
table.push_back(entry);
}
buildHuffmanTable(root->left, code + "0", table);
buildHuffmanTable(root->right, code + "1", table);
}
使用示例:
cpp
int main() {
vector<pair<char, int>> data = {{'a', 5}, {'b', 9}, {'c', 12}, {'d', 13}, {'e', 16}, {'f', 45}};
HuffmanNode* root = buildHuffmanTree(data);
vector<HuffmanEntry> table;
buildHuffmanTable(root, "", table);
// 输出哈夫曼表
for (auto entry : table) {
cout << entry.data << ": " << entry.code << endl;
}
return 0;
}
这样,就可以通过构造哈夫曼树和哈夫曼表来实现对数据的编码和解码操作。