哈夫曼树算法

////////////////////////////////////////////

//哈夫曼树算法 模式匹配 				  //

//Author:Wang Yong				  		  //	

//Date:	2010.8.19				  		  //

////////////////////////////////////////////





#include <stdio.h>

#include <stdlib.h>



#define MAX 100000

#define N 100

////////////////////////////////////////////



//定义哈夫曼树的根结点类型



typedef struct				//根据哈夫曼树的2N-1特点,采用顺序存储表示 

{

	int weight;				//根节点的全知 

	int parrent,lchild,rchild;//结点的双亲,孩子的位置 				

} HuffmTree;



////////////////////////////////////////////



//哈夫曼树编码的每个结点类型

typedef struct 

{

	char code[N];		//存放当前的哈夫曼编码 

	int start;			//输出起始位置 

}HCode; 



////////////////////////////////////////////



//构造哈夫曼树, n为初始森林中的结点数



void CreatHuffmTree(HuffmTree tree[],int n)

{

	if(n <= 1)	return;				//少于一个结点,则独立成为一个哈夫曼树 

	

	int i;

	for(i = 1; i <= 2*n-1; i++)		//将tree[i]赋初始值 

	{

		tree[i].weight = 0;

		tree[i].lchild = tree[i].rchild = tree[i].parrent = -1;

	}

	int w;

	for(i = 1 ; i <= n ; i++)		//将初始的n个结点赋值权值 

	{

		scanf("%d",&w);

		tree[i].weight = w;

	}

	int j;

	for(i = n+1; i <= 2*n-1;i++ )	//构造HuffmTree 

	{

		int min1 , min2;

		min1 = min2 = MAX;

		int l,r;

		l = r = -1;

		for(j = 1; j <= i-1;j++)	//每次合并之后多出一个根节点,放入其中 

		{

			if(tree[j].parrent == -1 && tree[j].weight < min1)//选择合并的左孩子结点 

			{

				min2 = min1;

				r = l;

				min1 = tree[j].weight;

				l = j;

			}

			else if(tree[j].parrent == -1 && tree[j].weight < min2)//选择合并的右孩子结点 

			{

				min2 = tree[j].weight;

				r = j;

			}

		}

			tree[i].weight = tree[l].weight + tree[r].weight;



			tree[l].parrent = tree[r].parrent = i;



			tree[i].lchild = l;tree[i].rchild = r;



	} 

} 



///////////////////////////////////////////////////////////////



//哈夫曼编码

 

void CreatHCode(HuffmTree tree[],HCode cd[],int n)

{

	HCode hfmcd;

	int i,j,c,p;

	for(i = 1 ; i <= n;i++)

	{

		hfmcd.start  = n;		

		c = i;		

		p = tree[c].parrent;

		while(p != -1)

		{

			if (c == tree[p].lchild)

				hfmcd.code[hfmcd.start--] = '0';

			else if(c == tree[p].rchild)

				hfmcd.code[hfmcd.start--] = '1';

			c = p;

			p = tree[p].parrent;

		}

		hfmcd.start++;

		for(j = hfmcd.start ; j <= n ; j++)

			cd[i].code[j] = hfmcd.code[j];

		cd[i].start = hfmcd.start;

	} 

}



//////////////////////////////////////////////////////////////

int main()

{

	int i,j;

	int n;

	printf("请输出初始结点个数:");

	scanf("%d",&n);

	HuffmTree tree[2*n];

	HCode cd[n+1];

	CreatHuffmTree(tree,n);

	CreatHCode(tree,cd,n);

	for(i = 1 ; i <= n; i++)

	{

		for(j = cd[i].start; j <= n;j++)

			printf("%c",cd[i].code[j]);

		printf("\n");

	}

	return 0;

} 

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