一、思路
- 哈夫曼树目标建立一棵权值最小的树。
- 每次选取两个权值较小的结点作为左右子树构造一棵新的二叉树,置新构造的二叉树的权值为左右子树的权值之和。
- 将新构造的这棵二叉树作为我们的选取的一部分。
因为选取最小两个权值,可以用到堆,可以方便的获得最小值
C++中的堆是优先队列 priority_queue
需引用头文件#include<queue>
二、代码
#include<iostream>
#include<queue>
using namespace std;
typedef struct node{
int w;
struct node *lchild;
struct node *rchild;
node(int W){
w = W;
lchild = NULL;
rchild = NULL;
}
}TreeNode;
//堆中存储结构体类型,需手写排序
struct cmp{
bool operator ()(TreeNode* a, TreeNode* b){
return a->w > b->w;
}
};
int n;// 树节点个数
priority_queue<TreeNode*, vector<TreeNode*>, cmp> heap;//定义小根堆
void fastRead(){
ios::sync_with_stdio();
cin.tie();
}
void preorder(TreeNode* root){
if(!root) return;
cout << root->w << ' ';
preorder(root->lchild);
preorder(root->rchild);
}
void inorder(TreeNode* root){
if(!root) return;
inorder(root->lchild);
cout << root->w << ' ';
inorder(root->rchild);
}
void postorder(TreeNode* root){
if(!root) return;
inorder(root->lchild);
inorder(root->rchild);
cout << root->w << ' ';
}
void print(TreeNode* root){
puts("哈夫曼树前/中/后序序列:");
preorder(root);//前序输出哈夫曼树
puts("");
inorder(root);//中序输出哈夫曼树
puts("");
postorder(root);//后序输出哈夫曼树
puts("");
}
int main(){
fastRead();
cin >> n;
for(int i = 0; i < n; i++){
int w; cin >> w;
TreeNode* tmpNode = new TreeNode(w);
heap.push(tmpNode);
}
/*-------------建立哈夫曼树过程-------------*/
while(heap.size() >= 2){
auto l = heap.top(); heap.pop();
auto r = heap.top(); heap.pop();
auto tmp_parent = new TreeNode(l->w + r->w);
tmp_parent->lchild = l;
tmp_parent->rchild = r;
heap.push(tmp_parent);
}
/*------------------------------------------*/
TreeNode* root = heap.top();
print(root);
return 0;
}
/*
Test Case:
8
2 3 6 7 10 19 21 32
*/