思路:用优先队列模拟最小化堆的操作,然后用建二叉树的方法将结点连接好。
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
typedef struct tree
{
tree *l,*r;
int w;
char ch;
}tree;
struct ss //优先队列,模拟最小化堆,它其中变量的类型为struct tree *型
{
friend bool operator<(const ss &a,const ss &b)
{
if(a.v->w>=b.v->w) //定义优先级别,权值小的优先级别高
return 1;
else
return 0;
}
tree *v; //变量为哈夫曼树的指针变量
};
tree *root;
int n;
priority_queue<ss>q;
void creat(tree *s) //建树
{
ss t;
tree *parent; //父节点
int i;
for(i=0;i<n;i++) //n代表有多少个要输入的数据
{
int w;
//char ch;
scanf("%d",&w); //输入权值
//scanf("%c",&ch);
s=(tree *)malloc(sizeof(tree));
s->w=w;
//s->ch=ch;
s->l=s->r=NULL; //子节点都置为空
t.v=s; //将s这个指针赋值给优先队列中的变量
q.push(t); //进队列
}
while(q.size()!=1) //当优先对了里面只剩下一个元素时,要停止循环
{
ss tmp1,tmp2;
tmp1=q.top(); //哈夫曼树,是两个最小权值的合成一个大的权值,再将这个大的权值加入队列
q.pop();
tmp2=q.top();
q.pop();
parent=(tree *)malloc(sizeof(tree));
parent->l=tmp1.v;
parent->r=tmp2.v;
parent->w=tmp1.v->w+tmp2.v->w;
t.v=parent;
q.push(t);
root=parent;
}
}
void libian(tree *root) //前序历遍哈夫曼树
{
if(root!=NULL)
{
printf("%d\t",root->w);
libian(root->l);
libian(root->r);
}
}
int main()
{
int i;
ss t;
root=NULL;
scanf("%d",&n);
creat(root);
libian(root);
return 0;
}