哈夫曼树、哈夫曼编码

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

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

}

 

你可能感兴趣的:(哈夫曼树)