# include <stdio.h>
# include <iostream>
# include <string.h>
using namespace std;


typedef struct			//define structure HuffmanTree
{   int weight;
int parent,lchild,rchild;
}HTNode,*HuffmanTree;

typedef char **  HuffmanCode;

void Select(HuffmanTree HT,int i,int &s1,int &s2) ;//选出HT树到i为止,权值最小且parent为0的2个节点
void HuffmanTreeing(HuffmanTree &HT,int *w,int n);//构建哈夫曼树函数 
void HuffmanCoding(HuffmanTree HT,HuffmanCode &HC,int n); //建立哈夫曼树编码
void output(HuffmanTree HT,int m);//输出哈夫曼树

int main()            		
{ 
	HuffmanTree HT;
	HuffmanCode HC;
	int n,i;
	int *w;
	scanf("%d",&n);
	w=(int *)malloc(n*sizeof(int));
  	for(i=0;i<n;i++)
	{
		scanf("%d",&w[i]);		
	}
	HuffmanTreeing( HT , w  ,n  );	
	HuffmanCoding( HT,  HC ,n   );	
	cout<<"哈夫曼编码:"<<endl;
	for(i=1;i<=n;i++)
    {
		printf("HT[%d] node's Huffman code is: %s\n",i,HC[i]);
	}	
	return 0;
}

void Select(HuffmanTree HT,int i,int &s1,int &s2)  
{ 	//选出HT树到i为止,权值最小且parent为0的2个节点
	//s1 is the least of HT[].weight
	//s2 is the second least of HT[].weight
	int j,k=1;                	
	while(HT[k].parent!=0)	   
		k++;
	s1=k;
	for(j=1;  j<=i  ;++j)
		if(HT[j].parent==0 &&   HT[j].weight <  HT[s1].weight     )
			s1=j;
	k=1;
	while( HT[k].parent!=0||  k==s1   ) 
		k++;
	s2=k;
	for(j=1;j<=i;++j)
		if(   HT[j].parent==0   && HT[j].weight<HT[s2].weight && j!=s1)
			s2=j;

} 


void HuffmanTreeing(HuffmanTree &HT,int *w,int n) //构建哈夫曼树函数
{ // w存放n个字符的权值(均>0),构造赫夫曼树HT
	int m,i,s1,s2;
	
	if(n<=1)
		return;
	m= 2*n-1 ;
	HT=(HuffmanTree) malloc( (m+1)*sizeof(   HTNode     ) );
	for( i=1; i<=n; ++i )	//initial HT[1...n]
	{ 
		HT[i].weight=  w[i-1] ;
        HT[i].parent = 0;
        HT[i].lchild = 0;
        HT[i].rchild = 0;
	}
	for(  ; i<=m; ++i )			//initial HT[n+1...2*n1]
	{
        HT[i].weight = 0;  
        HT[i].parent = 0;
        HT[i].lchild = 0;
        HT[i].rchild = 0;
	}
	for( i=n+1; i<=m; ++i )
	{  
		Select(HT,i-1,s1,s2);	// 在HT[1~i-1]中选择parent为0且weight最小的两个结点,其序号分别为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 ;
	}	

}   


void HuffmanCoding(HuffmanTree HT,HuffmanCode &HC,int n) //建立哈夫曼树编码
{ 	// 根据赫夫曼树HT,求出n个字符的赫夫曼编码HC
	/********** Begin **********/
	char *cd;
	int i,start;
	unsigned c,f;
	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(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);

	/********** End **********/ 
} 

void output(HuffmanTree HT,int m)
{ //输出哈夫曼树
	for(int i=1;i<=m;++i)
	{   
		cout<<"HT["<<i<<"] ="<<HT[i].weight<<"\t"<<HT[i]. parent<<"\t";
		cout<<"\t" <<HT[i]. lchild <<"\t" <<HT[i]. rchild<<endl;
	}
}
posted on 2024-06-20 17:52  findscripter  阅读(27)  评论(0)    收藏  举报