haffmanTree(哈夫曼树)的相关操作 + 两种遍历哈弗曼算法+ 无递归遍历+ 叶子节点遍历

#include<iostream>
using namespace std ;

typedef struct node//节点的信息
{
	int weight ;
	int parent , lchild , rchild ;
}node , *HuffmanTree;
typedef char * * HuffmanCode ;

/*按升序排*/
int cmp(const void *a , const void *b)
{
	return ((HuffmanTree)a)->weight - ((HuffmanTree)b)->weight ;
}

/*在HT[1....i-1]中选出parent 为0 ,且weight最小的两个数,返回他们的序号*/
void Select(HuffmanTree HT , int n , int &s1 , int &s2 )
{
	qsort(HT,n,sizeof(HT[1]), cmp );
	for(int i = 1 ; i <= n ; i ++)
	{
		if(HT[i].parent == 0 )
		{
			s1 = i ;
			i ++ ;
			break;
		}
	}
	for( ; i <= n ; i ++)
	{
		if(HT[i].parent == 0 )
		{
			s2 = i ;
			break;
		}
	}
	return ;
}

/*创建哈夫曼树和求得哈弗曼编码*/
void Hffmancode(HuffmanTree &HT , HuffmanCode &HC , int *w , int n )
{
	if(n < 1 )	return ;
	int i,m = 2*n - 1 ; //n节点的树有2*n-1个节点
	HT = (HuffmanTree ) malloc((m+1)*sizeof(node));
	HuffmanTree p ;
	for( i = 0 ,p = HT ; i <= n ; i ++,p++ , w ++ )  //初始化叶子节点
	{
		
		p->weight = *w ;
		p->parent = 0 ;
		p->lchild = 0 ;
		p->rchild = 0 ;
	}
	for(; i <= m ; p++,i++) //初始化剩下的节点
	{
		p->weight = 0 ;
		p->parent = 0 ;
		p->lchild = 0 ;
		p->rchild = 0 ;
	}
	for( i = n+1 ; i<= m ; i ++)
	{
		int s1 , s2 ;
		/*在HT[1....i-1]中选出parent 为0 ,且weight最小的两个数,返回他们的序号*/
		Select(HT , i - 1 , s1 , s2 );
		HT[s1].parent = i ;	HT[s2].parent = i ;
		HT[i].lchild = s1 ; HT[i].rchild = s2 ;
		HT[i].weight = HT[s1].weight + HT[s2].weight ;
	}
	
	/*从叶子节点反序遍历整颗树,并求得哈弗编码*/
	HC = (HuffmanCode )malloc((n+1)*sizeof(node)) ;
	char *cd ;
	cd = (char *)malloc(n*sizeof(char)) ;
	cd[n-1] = '\0' ;
	for( i= 1; i <= n ; i++)
	{
		int start = n-1 , c , f ;
		for( c = i , f = HT[i].parent ; f!= 0 ; c = f , f = HT[f].parent )
			if(HT[f].lchild == c)
				cd[--start] = '0';
			else
				cd[--start] = '1' ;
		
		HC[i] = (char *)malloc((n-start)*sizeof(char) ) ;
		strcpy(HC[i] , &cd[start]);
	}
	free(cd);
}

/*无递归从根节点求哈弗曼编码*/
void Hfffin(HuffmanTree HT, HuffmanCode &hc,int n , int m)
{
	hc = (HuffmanCode)malloc((m+1)*sizeof(char *));
	int p = m ;
	int len = 0 ;
	for(int i = 1; i <= m ; i ++)
		HT[i].weight = 0 ;
	char cd[10] ;
	while(p>0)
	{
		if(HT[p].weight == 0 )
		{
			HT[p].weight = 1;
			if(HT[p].lchild != 0 )
			{
				p = HT[p].lchild ;
				cd[len ++] = '0' ;
			}
			else if(HT[p].rchild == 0 )
			{
				hc[p] = (char *)malloc((len + 1)*sizeof(char));
				cd[len] = '\0' ;
				strcpy(hc[p],cd);
			}
		}
		else if(HT[p].weight == 1)
		{
			HT[p].weight = 2;
			if(HT[p].rchild != 0 )
			{
				p = HT[p].rchild ;
				cd[len++] = '1';
			}
		}
		else
			{
				HT[p].weight = 0 ;
				p = HT[p].parent ;
				--len ;
			}
	}
}
int main(void)
{
	int w[100] ;
	for(int i = 0 ; i < 10 ; i ++)
		w[i] = i + 1 ;
	HuffmanTree HT ;
	HuffmanCode HC ;
	cout<<"建立哈夫曼树,并求得哈弗曼编码"<<endl;
	Hffmancode(HT , HC , w , 10); 
	
	for( i = 1 ; i <= 10 ; i++)
		cout<<i<<"的哈弗编码是:"<< HC[i]<<endl;
	cout<<endl;
	cout<<"无递归遍历整颗树"<<endl;
	HuffmanCode hc ;
	Hfffin(HT ,hc,10 , 19) ;
	for( i = 1 ; i <= 10 ; i++)
		cout<<i<<"的哈弗编码是:"<< HC[i]<<endl;
	return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值