哈夫曼树算法

////////////////////////////////////////////
//哈夫曼树算法 模式匹配 				  //
//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;
} 
原文地址:https://www.cnblogs.com/newwy/p/1847473.html