#include <stdio.h>
typedef struct huffman_node { int weight ; char value ; struct huffman_node *lchild , *rchild , *pchild ; } huffman_node , *huffman_tree;
huffman_tree create_huffman_code ( char *, int *, int);
void tran_huffman_str_2_bin( huffman_tree , char , char * );
char tran_huffman_bin_2_str(huffman_tree , char * );
int main()
{
char huffman_char[] = {'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z' };
int huffman_weight[] = {1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 ,10 ,11 ,12 , 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26 };
int m ,n ;
m = sizeof(huffman_char)/sizeof(char);
n = sizeof(huffman_weight)/sizeof(int);
huffman_tree ht = create_huffman_code ( huffman_char , huffman_weight , m );
//printf("%c\n" , ht->lchild->value);
//printf("%d\n" , ht->lchild->weight);
char str[30];
tran_huffman_str_2_bin(ht , 'D' , str );
printf("%s \n" , str );
printf("%c\n" , tran_huffman_bin_2_str(ht , str) );
getchar();
return 0;
}
huffman_tree create_huffman_code ( char *huffman_char , int *huffman_weight , int num)
{
int total_num = 2* num - 1 ;
/*
** n0 = n2 + 1 ;
** no = num ;
** n1 = 0;
** => total_num = 2* num - 1
*/
huffman_node hn[num];
int i ;
int j ;
//sort
for (i = 0 ; i < num ; i++)
{
for (j = 0 ; j < i ; j++ )
{
if ( *(huffman_weight + j) > *(huffman_weight + j + 1 ) )
{
int tmp_int = *(huffman_weight + j);
*(huffman_weight + j) = *(huffman_weight + j + 1 );
*(huffman_weight + j + 1 ) = tmp_int;
int tmp_char = *(huffman_char + j);
*(huffman_char + j) = *(huffman_char + j + 1 );
*(huffman_char + j + 1 ) = tmp_char;
}
}
}
for ( i = 0 ; i < num ; i++ )
{
(hn+i)->weight = *(huffman_weight + i);
(hn+i)->value = *(huffman_char + i);
(hn+i)->lchild = NULL;
(hn+i)->rchild = NULL;
(hn+i)->pchild = NULL;
}
j=0;
huffman_node *hn_tmp1 = ( huffman_node * ) malloc( sizeof(huffman_node) );
hn_tmp1->weight = (hn+j)->weight;
hn_tmp1->value = (hn+j)->value;
hn_tmp1->lchild = NULL;
hn_tmp1->rchild = NULL;
hn_tmp1->pchild = NULL;
j++;
huffman_node *hn_tmp2 = ( huffman_node * ) malloc( sizeof(huffman_node) );
hn_tmp2->weight = (hn+j)->weight;
hn_tmp2->value = (hn+j)->value;
hn_tmp2->lchild = NULL;
hn_tmp2->rchild = NULL;
hn_tmp2->pchild = NULL;
huffman_tree ht = ( huffman_node * ) malloc( sizeof(huffman_node) );
ht->lchild = hn_tmp1;
ht->rchild = hn_tmp2;
ht->weight = hn_tmp1->weight + hn_tmp2->weight;
ht->value = ' ';
ht->pchild = NULL;
hn_tmp1->pchild = ht;
hn_tmp2->pchild = ht;
for ( i = 2 ; i < total_num-1 ; )
{
hn_tmp2 = ht;
i++;i++;j++;
hn_tmp1 = ( huffman_node * ) malloc( sizeof(huffman_node) );
hn_tmp1->weight = (hn+j)->weight;
hn_tmp1->value = (hn+j)->value;
hn_tmp1->lchild = NULL;
hn_tmp1->rchild = NULL;
ht = ( huffman_node * ) malloc( sizeof(huffman_node) );
ht->lchild = hn_tmp1;
ht->rchild = hn_tmp2;
ht->weight = hn_tmp1->weight + hn_tmp2->weight;
ht->pchild = NULL;
hn_tmp1->pchild = ht;
hn_tmp2->pchild = ht;
}
return ht;
}
void tran_huffman_str_2_bin( huffman_tree ht , char p , char *str )
{
int i = 0 ;
while (1)
{
if (ht->lchild->value == p)
{
*(str+i) = '0';
*(str+i+1) = '\0';
return ;
}
else
{
if (ht->rchild->value == p)
{
*(str+i) = '1';
*(str+i+1) = '\0';
return ;
}
else
{
ht = ht->rchild;
*(str+i) = '1';
}
}
i++;
}
}
char tran_huffman_bin_2_str(huffman_tree ht , char *str )
{
int i = 0 ;
while ( *(str+i) != '\0' )
{
if( *( str+ i ) == '0' )
{
return ht->lchild->value;
}
else
{
if(ht->rchild->rchild == NULL )
{
return ht->rchild->value;
}
else
{
ht = ht->rchild;
}
}
++i;
}
}