#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*
構造赫夫曼樹
n個葉子 2n+1個結點
一組帶權值的葉子
找權值最小的兩個葉子 ( 尋找最小兩個權值的葉子
生成新結點
其權值爲兩葉子權值之和
兩葉子的父節點改爲新生成結點
新生成結點 父節點爲 0 。 左右孩子結點是兩葉子 (規定權值小的在左 大的在右
生成赫夫曼編碼
二維數組
for循環
從葉子到根 。n-1 = '\0' start = n - 1 start--
n - 1 組二進制編碼 長度爲 n-start
*/
//-------------------赫夫曼樹和赫夫曼編碼的存儲表示----------------------
typedef int ElemType ;
typedef struct HTnode{
ElemType data ;
int weight ;
int parent ;
int Lchild , Rchild ;
}HTNode , *HuffmanTree ; //動態分配數組存儲赫夫曼樹
typedef char * * Huffmancode ; //動態分配數組存儲赫夫曼樹
void CreateHuffmanTree(HuffmanTree * T , int * w , int n)
{
int i ;
int j ;
int min1 ;
int min2 ;
*T = (HuffmanTree)malloc(sizeof(HTNode) * (n+1) ) ;
for(i = 1 ; i <= n ; i++)
{
(*T)[i].data = i ;
(*T)[i].weight = w[i-1] ;
(*T)[i].parent = 0 ;
(*T)[i].Lchild = 0 ;
(*T)[i].Rchild = 0 ;
}
for( i = n + 1 ; i <= 2*n-1 ; i++)
{
for( j = 1 ; j < i ; j++)
{
if((*T)[j].parent == 0 )
{
min1 =j ;
break ;
}
}
for( j = 1 ; j < i ; j++)
{
if((*T)[j].parent != 0 )continue ;
if( (*T)[j].weight < (*T)[min1].weight)
{
min1 = j ;
}
}
for(j = 1 ; j < i ; j++)
{
if((*T)[j].parent == 0 && j != min1)
{
min2 = j ;
break;
}
}
for( j = 1 ; j < i ; j++)
{
if((*T)[j].parent != 0 )continue ;
if( (*T)[j].weight < (*T)[min2].weight && j != min1)
{
min2 = j ;
}
}
T[i]= (HuffmanTree)malloc(sizeof(HTNode));
(*T)[i].data = i ;
(*T)[i].weight = (*T)[min1].weight + (*T)[min2].weight ;
(*T)[i].parent = 0 ;
(*T)[i].Lchild = (*T)[min1].data ;
(*T)[i].Rchild = (*T)[min2].data ;
(*T)[min1].parent = (*T)[i].data ;
(*T)[min2].parent = (*T)[i].data ;
}
}
void CreateHuffmanCode(HuffmanTree HT , Huffmancode *HC , int n)
{
int i ;
int start ;
int c ;
int f ;
char *cd ;
*HC = malloc(sizeof(char*) * (n+1) ) ;
cd = malloc(sizeof(char) * n) ;
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(c == HT[f].Lchild)
cd[--start] = '0' ;
else
cd[--start] = '1' ;
(*HC)[i] = malloc(sizeof(char*)*(n-start) ) ;
strcpy((*HC)[i] , &cd[start]) ;
printf("\nHT[%d] node's Huffman code is : %s" , i , (*HC)[i]) ;
}
printf("\n");
free(cd) ;
}
void print(HuffmanTree T , int n)
{
int i = 0 ;
while( i ++<2*n-1)
{
printf("%d %d %d %d %d\n" , T[i].data , T[i].weight , T[i].parent , T[i].Lchild , T[i].Rchild ) ;
}
}
int main()
{
HuffmanTree HT ;
Huffmancode HC ;
int *w ;
int n ;
int i = 0 ;
printf("有多少葉子:");
scanf("%d" , &n) ;
w = (int *)malloc(sizeof(int) *n) ;
printf("\n請輸入權值:");
while( i < n )
{
scanf("%d" , &w[i] ) ;
i++;
}
CreateHuffmanTree(&HT,w , n) ;
print(HT , n) ;
CreateHuffmanCode( HT , &HC , n) ;
return 0;
}
赫夫曼樹和赫夫曼編碼 (純C)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.