贪心算法:构建Huffman Tree的时候先取出频度最小的两个点分别作为左子树和右子树。
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
struct Node{
char ch;
int fre; //frequency
string huffCode;
Node *left; //0 stands for "left"
Node *right; //1 stands for "right"
};
bool freCmp(Node a, Node b){
return a.fre > b.fre;
}
void Traversal(Node *root){
if(root){
if(!root->left && !root->right) cout << root->ch << ' ' << root->huffCode << endl;
if(root->left){
root->left->huffCode = root->huffCode + '0';
Traversal(root->left);
}
if(root->right){
root->right->huffCode = root->huffCode + '1';
Traversal(root->right);
}
}
}
int main(){
int N, temp_fre;
Node *root;
char temp_ch;
vector<Node> v;
cin >> N;
//读取数据
for(int i = 0; i < N; i++){
Node *temp = new Node;
cin >> temp->ch >> temp->fre;
temp->left = temp->right = NULL;
v.push_back(*temp);
}
//构建最小堆
make_heap(v.begin(), v.end(), freCmp);
//构建Huffman树
while(v.size() > 1){
Node *left = new Node;
Node *right = new Node;
Node *temp = new Node;
*left = v.front();
pop_heap(v.begin(), v.end(), freCmp);
v.pop_back();
*right = v.front();
pop_heap(v.begin(), v.end(), freCmp);
v.pop_back();
temp->ch = ' ';
temp->fre = left->fre + right->fre;
temp->left = left;
temp->right = right;
v.push_back(*temp);
push_heap(v.begin(), v.end(), freCmp);
}
root = &v.front();
root->huffCode = "";
//遍历
Traversal(root);
return 0;
}