哈夫曼树

哈夫曼树
#include  < cstdio >
#include 
< algorithm >
#include 
< vector >
#include 
< queue >
#include 
< string >

using   namespace  std;

struct  HTNode
{
    
int  weight, letter, lchild, rchild;
    
    HTNode(){}
    HTNode( 
int  a,  int  b,  int  c,  int  d ) :weight(a), letter(b), lchild(c), rchild(d) {}
};

struct   Info
{
    
int   num, lett, id;
    Info();
    Info( 
int  a,  int  c,   int  b ): num(a), lett(c), id(b) {}
};

bool   operator <  ( Info  const &  a, Info  const &  b )
{
    
return  a.num >  b.num;
}

int      num[ 26 ], len =   0 , root;
char     str[ 1000 ];
string   code[ 26 ];
vector
< HTNode >   ht;
priority_queue
< Info >   info;

void  buildtree();
void  codeht( int , string );
void  decode(  int , int );

void  input()                                   //   输入过程 
{
    printf(
" 注意:  该程序只处理大写字母, 其它字符不予处理\n " );
    printf(
" 请输入文本, 在最后另起一行按  F6  结束输入:\n " );
    
char  ch;
    
    memset( num, 
0 sizeof (num) );
    
while ( scanf( " %c " , & ch) !=  EOF )
        
if ( ch >=   ' A '   &&  ch <=   ' Z '  )  num[ch -   ' A ' ] ++ ;
        
    printf(
" 各字母个数为:\n " );
    
for ( int  i =   0 ; i <   26 ++ i )
    
if ( num[i] ) printf( " %c  %d\n " , i +   ' A ' , num[i] ); 
}

void  test()
{
    input();
    buildtree();
    codeht( root, 
""  );
    
    printf(
" 各字母的哈夫曼编码为:\n\n " ); 
    
for int  i =   0 ; i <   26 ++ i )
    
if ( num[i] ) printf( " %c  %s\n " , i +   ' A ' , code[i].c_str() );
    
    printf(
" \n\n\n请输入你要解码的字符串,不能有空格,并且输入合法\n " ); 
    scanf(
" %s " , str );
    
    printf(
" 解码后为:\n\n " ); 
    
    decode(
0 , root ); 
    printf(
" \n\n\n " );
}

void  codeht(  int  i,  string  s )                     //    编码过程 
{
    
if ( ht[i].lchild ==   - 1  )  
    {
        code[ ht[i].letter ]
=  s;
    }
    
else
    {
        codeht( ht[i].lchild, s
+   ' 0 '  );
        codeht( ht[i].rchild, s
+   ' 1 '  );
    }
}

void  decode(  int  i,  int  j )                       //    解码过程 
{
    
if ( ht[j].lchild ==   - 1   &&  ht[j].rchild ==   - 1  )
    {
        printf(
" %c " , ht[j].letter +   ' A '  );
        
if ( str[i] ) decode( i, root );
    }
    
else   if ! str[i] )  return ;
    
else   if ( str[i] ==   ' 0 '  )      decode( i +   1 , ht[j].lchild );
    
else   if ( str[i] ==   ' 1 '  )      decode( i +   1 , ht[j].rchild );
}

void  buildtree()                                 //    建树过程 
{
    len
=   0 ;
    
for int  i =   0 ; i <   26 ++ i )
    
if ( num[i] )
    {
        ht.push_back( HTNode( num[i], i, 
- 1 - 1  ) );
        info.push( Info( num[i], i, len
++  ) );
    }
    
    
if ( info.size() ==   1  ) {  root =   0 ;   return ;  }
    
    Info  a
=  info.top();  info.pop();
    Info  b
=  info.top();  info.pop();
    
    info.push( Info( a.num
+  b.num,  - 1 , len ++  ) );
    ht.push_back( HTNode( a.num
+  b.num,  - 1 , a.id, b.id ) );
    
    
while ( info.size() >   1  )
    {
        Info a
=  info.top(); info.pop();
        Info b
=  info.top(); info.pop();
        
        info.push( Info( a.num
+  b.num,  - 1 , len ++  ) );
        ht.push_back( HTNode( a.num
+  b.num,  - 1 , a.id, b.id ) );
    }    
    
    root
=  info.top().id;
}

int  main()
{
    test();
    
    system(
" pause " );
    
return   0 ;
}

/*

7 5 2 4 6

*/

你可能感兴趣的:(哈夫曼树)