#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;
}
haffmanTree(哈夫曼树)的相关操作 + 两种遍历哈弗曼算法+ 无递归遍历+ 叶子节点遍历
最新推荐文章于 2022-12-14 19:19:45 发布