# include <malloc.h>
# include <stdio.h>
# include <string.h>
# define MAX 100
typedef struct
{
int weight;
int parent, lchild, rchild;
char c1;
} HTNode, * HuffmanCode;
typedef struct
{
char cd[ MAX] ;
int start;
} HCode;
typedef struct node
{
char ch;
int count;
int n;
struct node * next;
} linknode, * linklist;
void character_count ( char * str, linklist * L) ;
void print ( linklist L) ;
int count ( linklist L) ;
void sort ( linklist * L) ;
void Insert ( linklist * L, int weight1, int n1) ;
void Create_HuffmanTree ( HuffmanCode * HT, linklist * L) ;
void HuffmanCoding ( HuffmanCode HT, HCode * hcd, int n, char * str) ;
void IPT ( ) ;
# include "huffman.h"
void character_count ( char * str, linklist * L)
{
int n[ 26 ] = { 0 } ;
char c[ 26 ] = { '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 i= 0 , j= 1 ;
for ( i= 0 ; i< strlen ( str) ; i++ )
{
switch ( str[ i] )
{
case 'a' : n[ 0 ] ++ ; break ;
case 'b' : n[ 1 ] ++ ; break ;
case 'c' : n[ 2 ] ++ ; break ;
case 'd' : n[ 3 ] ++ ; break ;
case 'e' : n[ 4 ] ++ ; break ;
case 'f' : n[ 5 ] ++ ; break ;
case 'g' : n[ 6 ] ++ ; break ;
case 'h' : n[ 7 ] ++ ; break ;
case 'i' : n[ 8 ] ++ ; break ;
case 'j' : n[ 9 ] ++ ; break ;
case 'k' : n[ 10 ] ++ ; break ;
case 'l' : n[ 11 ] ++ ; break ;
case 'm' : n[ 12 ] ++ ; break ;
case 'n' : n[ 13 ] ++ ; break ;
case 'o' : n[ 14 ] ++ ; break ;
case 'p' : n[ 15 ] ++ ; break ;
case 'q' : n[ 16 ] ++ ; break ;
case 'r' : n[ 17 ] ++ ; break ;
case 's' : n[ 18 ] ++ ; break ;
case 't' : n[ 19 ] ++ ; break ;
case 'u' : n[ 20 ] ++ ; break ;
case 'v' : n[ 21 ] ++ ; break ;
case 'w' : n[ 22 ] ++ ; break ;
case 'x' : n[ 23 ] ++ ; break ;
case 'y' : n[ 24 ] ++ ; break ;
case 'z' : n[ 25 ] ++ ; break ;
}
}
( * L) = ( linklist) malloc ( sizeof ( linknode) ) ;
linklist p, q;
p= * L;
for ( i= 0 , j= 1 ; i< 26 ; i++ )
{
if ( n[ i] != 0 )
{
q= ( linklist) malloc ( sizeof ( linknode) ) ;
q-> n= j++ ;
q-> ch= c[ i] ;
q-> count= n[ i] ;
p-> next= q;
p= q;
}
}
p-> next= NULL ;
}
void print ( linklist L)
{
linklist p= L-> next;
while ( p)
{
printf ( "%c:%d " , p-> ch, p-> count) ;
p= p-> next;
}
}
int count ( linklist L)
{
linklist p= L-> next;
int num= 0 ;
while ( p)
{
num++ ;
p= p-> next;
}
return num;
}
void sort ( linklist * L)
{
linklist p, q, r;
int i= 0 ;
i= count ( * L) ;
while ( i-- > 0 )
{
p= * L;
while ( p-> next-> next)
{
q= p-> next; r= q-> next;
if ( q-> count> r-> count)
{
q-> next= r-> next;
p-> next= r;
r-> next= q;
}
p= p-> next;
}
}
}
void Insert ( linklist * L, int weight1, int n1)
{
linklist p;
p= ( linklist) malloc ( sizeof ( linknode) ) ;
p-> n= n1;
p-> ch= '*' ;
p-> count= weight1;
p-> next= ( * L) -> next;
( * L) -> next= p;
}
void Create_HuffmanTree ( HuffmanCode * HT, linklist * L)
{
int n= count ( * L) ;
int m= 0 ;
int i= 0 ;
linklist p, q, r;
HuffmanCode T;
p= ( linklist) malloc ( sizeof ( linknode) ) ;
( * HT) = ( HuffmanCode) malloc ( ( 2 * n) * sizeof ( HTNode) ) ;
p= ( * L) -> next;
for ( i= 1 ; i<= n&& p; ++ i)
{
( * HT) [ i] . c1= p-> ch;
( * HT) [ i] . weight= p-> count;
( * HT) [ i] . parent= 0 ;
( * HT) [ i] . lchild= 0 ;
( * HT) [ i] . rchild= 0 ;
p= p-> next;
}
m= 2 * n- 1 ;
for ( i= n+ 1 ; i<= m; ++ i)
{
( * HT) [ i] . c1= '*' ;
( * HT) [ i] . weight= 0 ;
( * HT) [ i] . parent= 0 ;
( * HT) [ i] . lchild= 0 ;
( * HT) [ i] . rchild= 0 ;
}
for ( i= n+ 1 ; i<= m; i++ )
{
sort ( L) ;
q= ( * L) -> next;
r= q-> next;
( * HT) [ q-> n] . parent= i;
( * HT) [ r-> n] . parent= i;
( * HT) [ i] . lchild= q-> n;
( * HT) [ i] . rchild= r-> n;
( * HT) [ i] . weight= ( * HT) [ q-> n] . weight+ ( * HT) [ r-> n] . weight;
( * L) -> next= r-> next;
free ( q) ;
free ( r) ;
Insert ( L, ( * HT) [ i] . weight, i) ;
}
for ( i= 1 ; i<= m; i++ )
{
printf ( "%d %d %d %d %d" , i, ( * HT) [ i] . weight, ( * HT) [ i] . parent, ( * HT) [ i] . lchild, ( * HT) [ i] . rchild) ;
printf ( "\n" ) ;
}
}
void HuffmanCoding ( HuffmanCode HT, HCode * hcd, int n, char * str)
{
HCode hc;
int i= 0 , c= 0 , f= 0 , j= 0 , m= 0 ;
for ( i= 1 ; i<= n; i++ )
{
hc. start= n- 1 ;
c= i;
f= HT[ i] . parent;
while ( f!= 0 )
{
if ( HT[ f] . lchild== c)
hc. cd[ hc. start-- ] = '0' ;
else
hc. cd[ hc. start-- ] = '1' ;
c= f;
f= HT[ f] . parent;
}
hc. start++ ;
hcd[ i] = hc;
}
for ( i= 1 ; i<= n; i++ )
{
printf ( "%c: " , HT[ i] . c1) ;
for ( j= hcd[ i] . start; j<= n- 1 ; j++ )
printf ( "%c" , hcd[ i] . cd[ j] ) ;
printf ( " " ) ;
}
printf ( "\n" ) ;
for ( j= 0 ; j< strlen ( str) ; j++ )
{
for ( i= 1 ; i<= n; i++ )
{
if ( str[ j] == HT[ i] . c1)
break ;
}
for ( m= hcd[ i] . start; m<= n- 1 ; m++ )
printf ( "%c" , hcd[ i] . cd[ m] ) ;
}
}
# include "huffman.h"
void IPT ( )
{
char a[ 100 ] = { '0' } ;
linklist L;
L= ( linklist) malloc ( sizeof ( linknode) ) ;
HuffmanCode HT;
int n= 0 ;
while ( 1 )
{
scanf ( "%s" , a) ;
if ( ! strcmp ( a, "0" ) )
break ;
character_count ( a, & L) ;
print ( L) ;
if ( count ( L) == 1 )
{
printf ( "\n" ) ;
printf ( "1 %d 0 0 0\n" , strlen ( a) ) ;
printf ( "编码为1\n" ) ;
}
else
{
n= count ( L) ;
HCode hcd[ n+ 1 ] ;
printf ( "\n" ) ;
Create_HuffmanTree ( & HT, & L) ;
HuffmanCoding ( HT, hcd, n, a) ;
printf ( "\n" ) ;
}
printf ( "%s\n" , a) ;
}
}
# include "huffman.h"
int main ( )
{
IPT ( ) ;
return 0 ;
}