#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)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.