通过字符出现的频率设置权重进行哈夫曼编码
#pragma once
#include<iostream>
#include<queue>
#include<string>
#include<utility>
#include<unordered_map>
struct Node {
Node* left=nullptr;
Node* right=nullptr;
int weight = 0;
char data='\0';
bool isLeaf = false;
};
struct cmp{
bool operator ()(Node* a, Node* b) {
return (a->weight > b->weight);
}
};
class HuffmanTree {
private:
std::vector<std::pair<char, std::string>> code;
size_t size = 0;
Node* top;
void dfs(Node* node, int pos, std::string& s);
public:
HuffmanTree() = default;
HuffmanTree(std::string data);
~HuffmanTree();
void HuffmanCode();
};
HuffmanTree::HuffmanTree(std::string data) {
std::unordered_map<char, int> freqMap;
std::priority_queue<Node*, std::vector<Node*>,cmp> queue;
for(auto e : data) freqMap[e]++;
this->size = freqMap.size();
for (auto& e : freqMap) {
Node* node = new Node;
node->data = e.first;
node->weight = e.second;
node->isLeaf = true;
queue.push(node);
}
while (queue.size() > 1) {
//queue.size() > 1 保证无论奇数还是偶数最后queue都只剩一个节点
Node* node1 = queue.top();
queue.pop();
Node* node2 = queue.top();
queue.pop();
Node* parent = new Node;
parent->weight = node1->weight + node2->weight;
if (node1->weight > node2->weight) {
parent->left = node1;
parent->right = node2;
}
else {
parent->left = node2;
parent->right = node1;
}
queue.push(parent);
}
top = queue.top();
}
void erase(Node* data) {
if (nullptr == data)return;
erase(data->left);
erase(data->right);
delete data;
}
HuffmanTree::~HuffmanTree() {
erase(this->top);
}
void HuffmanTree::dfs(Node* node,int pos,std::string& s){
if (node == nullptr) return;
if (pos == 0) s += '0';
else s += '1';
dfs(node->left,0,s);
dfs(node->right,1,s);
if (true == node->isLeaf) {
this->code.emplace_back(std::make_pair(node->data, s));
}
s.pop_back();
}
inline void HuffmanTree::HuffmanCode(){
std::string s = "";
dfs(this->top,0,s);
sort(this->code.begin(), this->code.end(), [](auto a, auto b) {
return a.first < b.first;
});
for (auto& e : this->code) {
std::cout << e.first << " " << e.second << std::endl;
}
}
调用如下
#include<iostream>
#include"HuffTree.h"
int main() {
HuffmanTree a("1231231232222211asdfdsdfcghjgh");
a.HuffmanCode();
}
编码如果没有出问题是这样的
1 0000
2 001
3 0110
a 000101
c 000100
d 0111
f 01000
g 01001
h 00011
j 01011
s 01010