哈夫曼树的定义
哈夫曼树的构造
补充:
当选择的两颗树的权值相同时,则要比较树的高度,更矮的树的头节点应当成为新节点的左子树。
哈夫曼树的代码实现
基于上面的构造过程,这里使用了小根堆来辅助实现。
#include<iostream>
#include<vector>
#include<queue>
using namespace std;
struct TreeNode{
char val;
int weight;
TreeNode* left;
TreeNode* right;
TreeNode(char x, int y ) : val(x), weight(y), left(nullptr), right(nullptr){}
TreeNode(char x, int y, TreeNode *left, TreeNode *right) : val(x), weight(y), left(left), right(right) {}
};
class cmp{
public:
bool operator()(TreeNode* a, TreeNode* b){
if(a->weight == b->weight){
return getheight(a) >= getheight(b);
}
return a->weight > b ->weight;
}
int getheight(TreeNode* node){
return node==nullptr ? 0 : max(getheight(node->left),getheight(node->right))+1;
}
};
class Huffman{
private:
TreeNode* root;
priority_queue<TreeNode*,vector<TreeNode*>,cmp> que;
void midOrderVisit(TreeNode* node){
if(node){
midOrderVisit(node->left);
cout<<"("<<node->val<<", "<<node->weight<<")";
midOrderVisit(node->right);
}
}
void preOrderVisit(TreeNode* node){
if(node){
cout<<"("<<node->val<<", "<<node->weight<<")";
midOrderVisit(node->left);
midOrderVisit(node->right);
}
}
int getheight(TreeNode* node){
return node==nullptr ? 0 : max(getheight(node->left),getheight(node->right))+1;
}
public:
void createHuffman(vector<pair<char,int>> data);
void midOrder();
void preOrder();
};
void Huffman::createHuffman(vector<pair<char,int>> data){
for(auto &[ch,weight] : data){
TreeNode* node = new TreeNode(ch,weight);
que.push(node);
}
while(!que.empty()){
TreeNode* node1 = que.top();
que.pop();
if(que.empty()){
que.push(node1);
break;
}
TreeNode* node2 = que.top();
que.pop();
TreeNode* node3;
if(node1->weight > node2->weight){
node3 = new TreeNode('#',node1->weight+node2->weight,node2,node1);
}else if(node1->weight < node2->weight){
node3 = new TreeNode('#',node1->weight+node2->weight,node1,node2);
}else{
if(getheight(node1)>getheight(node2)){
node3 = new TreeNode('#',node1->weight+node2->weight,node2,node1);
}else{
node3 = new TreeNode('#',node1->weight+node2->weight,node1,node2);
}
}
que.push(node3);
}
this->root = que.top();
}
void Huffman::midOrder(){
cout<<"中序遍历"<<endl;
midOrderVisit(root);
cout<<endl;
}
void Huffman::preOrder(){
cout<<"前序遍历"<<endl;
preOrderVisit(root);
cout<<endl;
}
int main(){
Huffman test;
vector<pair<char,int>> data;
data.emplace_back('a',7);
data.emplace_back('b',5);
data.emplace_back('c',2);
data.emplace_back('d',4);
test.createHuffman(data);
test.midOrder();
test.preOrder();
}