哈夫曼树、哈夫曼编码

思路:用优先队列模拟最小化堆的操作,然后用建二叉树的方法将结点连接好。

#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;
}

 

posted @ 2013-01-13 12:00  紫忆  阅读(295)  评论(0编辑  收藏  举报