赫夫曼编码

#include "stdio.h"
#define N 8
typedef struct
{
	unsigned int weight;//节点权重
	unsigned int parent,lchild,rchild;
}HTNode,*HuffmanTree;

typedef char ** HuffmanCode;
int useable[N*2]={0};

//选择最小的两个权值,已经选过了的就不能选了
void Select(HuffmanTree HT,int n,int *s1,int *s2)
{
	unsigned int max=0xffffffff;
	HuffmanTree p;
	int index;
	int i;

	for( p=HT,p++,i = 1; i <= n; i++,p++)
	{
		if( p->weight < max && 0==useable[i] )
		{
			max=p->weight;
			*s1=i;
		}
	}
 
	useable[*s1]=1;
	max=0xffffffff;
	for(p=HT,p++, i = 1; i <= n; i++,++p)
	{
		if( p->weight < max && 0==useable[i] )
		{
			max=p->weight;
			*s2=i;
		}
	 
	}
	useable[*s2]=1;
}

//w存放的是各个字符的权值
void HuffmanCoding(HuffmanTree* HT,HuffmanCode * HC,int *w,int n)
{
	int i,j,m;
	int s1,s2;
	int start,f;
	char * cd;
	HuffmanTree p ;
	if( n < 1 )
	{
		return;
	}
	m= 2*n-1;
	
	*HT=(HuffmanTree)malloc( (m+1)*sizeof(HTNode));
	memset(*HT,0,(m+1)*sizeof(HTNode));
	
	//将权值付给各个叶子节点
	for(p=*HT,i=1,p++;i<=n;++i,++p,++w)
	{
		p->weight=*w;
		printf("%d=%d\n",i,p->weight);
	}
	p=*HT;
	//建立赫夫曼树
	for(i=n+1;i<=m;i++)
	{
		Select(p,i-1,&s1,&s2);

		(*HT)[s1].parent=i;
		(*HT)[s2].parent=i;
		(*HT)[i].weight=(*HT)[s1].weight + (*HT)[s2].weight;
		
			(*HT)[i].lchild=s1;
			(*HT)[i].rchild=s2;		
		if(s1>n)
		{
			(*HT)[i].lchild=s2;
			(*HT)[i].rchild=s1;
		}
		printf("s1=%d,s2=%d   i=%d  (*HT)[i].weight=%d\n",s1,s2,i,(*HT)[i].weight);

	}
 
	//
	for(p=*HT,i=1;i<=m;++i,++p)
	{
		printf("%d=%d\n",i,p->weight);
	}	


	*HC=(HuffmanCode)malloc( (n+1)*sizeof(char*) );
	cd=(char *)malloc(n*sizeof(char));
	cd[n-1]='\0';
	
	//开始从叶子结点编码
	for(i=1;i<=n;i++)
	{
		start=n-1;
		for(j=i,f=(*HT)[i].parent; f!=0;  j=f,f=(*HT)[f].parent)
		{
			if( (*HT)[f].lchild == j)
			{
				cd[--start]='0';
			}
			else
			{
				cd[--start]='1';
			}

		}
		(*HC)[i]=(char *)malloc(  (n-start)*sizeof(char) );
		printf("%s\n",&cd[start]);
		strcpy((*HC)[i],&cd[start]);
	}
	free(cd);
	
}

void showcode(HuffmanTree HT,HuffmanCode HC,int n)
{
	int i;
	HuffmanTree p=HT;
	p++;
	for(i=1;i<=n;i++)
	{
		printf("i=%d  %d=%s\n",i,p->weight,HC[i]);
		p++;
	}
}
void main()
{
	int W[N]={5,29,7,8,14,23,3,11};
	HuffmanTree HT;
	HuffmanCode HC;
	HuffmanCoding(&HT,&HC,W,8);
	showcode( HT, HC, 8);
}

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值