哈夫曼编码的设计与实现

来源:互联网 发布:党员干部知敬畏 编辑:程序博客网 时间:2024/06/05 18:39
#include "stdafx.h"
#include <iostream>
#include <vector>
#include <list>
#include <algorithm>

const static int nBufferSize = 1024;

char g_szBuffer[ nBufferSize] = "ABCEFHDILASJBNDBBBBSAAUILDK" ;
int   g_nMaxNum = 100000;

enum  TREE_TAG_LEFT  = 0, TREE_TAG_RIGHT = 1, };

struct SBinaryTreeNode
{
      char  cByte ;
      int   nValue ;
      bool  bTakeTag ;

      SBinaryTreeNode* pParent ;
      SBinaryTreeNode* pLeftChild ;
      SBinaryTreeNode* pRightChild ;
};

struct SByteCoding
{
      char cByte ;
      std::list <int> listByteCodes;
};

//  ===========================================================================================================================
//  仿函数
//  ===========================================================================================================================

struct SFindByte
{
      SFindByte( char byte ): cByte( byte ) { }
      bool operator () ( SBinaryTreeNode* pNodeInfo )
     {
           if( pNodeInfo && pNodeInfo-> cByte == cByte )
               return true ;

           return false ;
     }
private :
      char cByte ;
};

struct SFindByteFormCodings
{
      SFindByteFormCodings ( char byte ): cByte ( byte ) { }
      bool operator () ( SByteCoding* pFindByte )
     {
           if( pFindByte && pFindByte-> cByte == cByte )
               return true ;

           return false ;
     }
private :
      char cByte ;
};
//  ===========================================================================================================================
//  仿函数
//  ===========================================================================================================================

int _tmain( int argc , _TCHAR* argv[])
{

      std::vector <SBinaryTreeNode*> vecBinaryNode;
      vecBinaryNode.clear ();
     
      std::vector <SBinaryTreeNode*>:: iterator iVecTreeNode ;
      char c ;
      for( int i = 0; i < nBufferSize && g_szBuffer[ i] != '/0'; ++i )
     {
           c = g_szBuffer [i];
           iVecTreeNode = std ::find_if( vecBinaryNode .begin(), vecBinaryNode.end (), SFindByte( c ) );
           if( iVecTreeNode == vecBinaryNode. end() )
          {
               SBinaryTreeNode* pBinaryNode = new SBinaryTreeNode ;
               if( !pBinaryNode )
              {
                    std::cout <<"Error 3"<< std::endl ;
                    system( "pause" );
                    return 0;
              }

               pBinaryNode->pLeftChild   = NULL;
               pBinaryNode->pRightChild = NULL;
               pBinaryNode->pParent      = NULL;

               pBinaryNode->cByte     = c;
               pBinaryNode->nValue    = 1;
               pBinaryNode->bTakeTag = false;

               vecBinaryNode.push_back ( pBinaryNode );
          }
           else
          {
               SBinaryTreeNode* pExistNode = (*iVecTreeNode );
               if( !pExistNode )
              {
                    std::cout <<"Error 4"<< std::endl ;
                    system( "pause" );
                    return 0;
              }

              ++ pExistNode->nValue ;
          }
     }

      // 通过vecBinaryNode  搭建哈夫曼树
      int nMinValue , nSecMinValue;
      int nByteNum = vecBinaryNode. size();
      for( int i = 1; i <= nByteNum - 1; ++i  // nSize - 1 次合并两个顶点
     {
           SBinaryTreeNode* pMinValueNode         = NULL;
           SBinaryTreeNode* pSecondMinValueNode   = NULL;
           nMinValue     = g_nMaxNum - 1;
           nSecMinValue  = g_nMaxNum ;
 
           std::vector <SBinaryTreeNode*>:: iterator iVecBegin = vecBinaryNode. begin();
           std::vector <SBinaryTreeNode*>:: iterator iVecEnd    = vecBinaryNode .end();
           for( ; iVecBegin != iVecEnd; ++ iVecBegin )
          {
               SBinaryTreeNode* pNowBinary = (*iVecBegin);
               if( !pNowBinary )
              {
                    std::cout <<"Error 5"<< std::endl ;
                    system( "pause" );
                    return 0;
              }

               if( true == pNowBinary-> bTakeTag )
                    continue;

               if( pNowBinary ->nValue < nMinValue )
              {
                    pSecondMinValueNode = pMinValueNode ;
                    pMinValueNode       = pNowBinary;

                    nSecMinValue = nMinValue ;
                    nMinValue    = pNowBinary-> nValue;
              }
               else if ( pNowBinary-> nValue >= nMinValue && pNowBinary ->nValue < nSecMinValue )
              {
                    pSecondMinValueNode = pNowBinary ;
                    nSecMinValue = pNowBinary ->nValue;
              }
          }

           if( !pMinValueNode || !pSecondMinValueNode )
          {
               std::cout <<"Error 6"<< std::endl ;
               system( "pause" );
               return 0;
          }

           SBinaryTreeNode* pConnectionNode = new SBinaryTreeNode ;
           if( !pConnectionNode )
          {
               std::cout <<"Error 7"<< std::endl ;
               system( "pause" );
               return 0;
          }

           pMinValueNode->bTakeTag = true;
           pMinValueNode->pParent   = pConnectionNode;

           pSecondMinValueNode->bTakeTag = true;
           pSecondMinValueNode->pParent   = pConnectionNode;

           pConnectionNode->bTakeTag     = false;
           pConnectionNode->cByte        = 0;
           pConnectionNode->nValue       = pMinValueNode ->nValue + pSecondMinValueNode->nValue ;
           pConnectionNode->pLeftChild   = pMinValueNode;
           pConnectionNode->pRightChild = pSecondMinValueNode ;
           pConnectionNode->pParent      = NULL;

           vecBinaryNode.push_back ( pConnectionNode );
     }

      // 求哈夫曼树的编码 同时求其跟结点
      std::vector <SByteCoding*> vecByteCoding;
      vecByteCoding.clear ();

      SBinaryTreeNode* pBinaryTreeRoot = NULL;
      std::vector <SBinaryTreeNode*>:: iterator iVecTreeBegin = vecBinaryNode. begin();
      std::vector <SBinaryTreeNode*>:: iterator iVecTreeEnd    = vecBinaryNode .end();
      for( ; iVecTreeBegin != iVecTreeEnd; ++ iVecTreeBegin )
     {
           SBinaryTreeNode* pFindLeafCodes = (*iVecTreeBegin );
           if( !pFindLeafCodes )
          {
               std::cout <<"Error 8"<< std::endl ;
               system( "pause" );
               return 0;
          }

           if( 0 != pFindLeafCodes ->cByte )
          {
               SByteCoding* pByteCoding = new SByteCoding;
               if( !pByteCoding )
              {
                    std::cout <<"Error 9"<< std::endl ;
                    system( "pause" );
                    return 0;
              }

               pByteCoding->cByte = pFindLeafCodes-> cByte;
               pByteCoding->listByteCodes .clear();

               while(1)
              {
                    if( pFindLeafCodes ->pParent != NULL )
                   {
                         if( pFindLeafCodes ->pParent-> pLeftChild == pFindLeafCodes )
                              pByteCoding->listByteCodes .push_front( TREE_TAG_LEFT );
                         else if ( pFindLeafCodes ->pParent-> pRightChild == pFindLeafCodes )
                              pByteCoding->listByteCodes .push_front( TREE_TAG_RIGHT );

                         pFindLeafCodes = pFindLeafCodes ->pParent;
                   }
                    else
                   {
                         if( NULL == pBinaryTreeRoot )
                              pBinaryTreeRoot = pFindLeafCodes ;

                         break;
                   }
              }

               vecByteCoding.push_back ( pByteCoding );
          }
     }

      // 输出编码格式 std::vector<SByteCoding*> vecByteCoding;
      std::vector <SByteCoding*>:: iterator iVecCodingBegin = vecByteCoding .begin();
      std::vector <SByteCoding*>:: iterator iVecCodingEnd    = vecByteCoding .end();
      for( ; iVecCodingBegin != iVecCodingEnd; ++iVecCodingBegin )
     {
           SByteCoding* pPrintByteCoding = (*iVecCodingBegin );
           if( !pPrintByteCoding )
          {
               std::cout <<"Error 10"<<std ::endl;
               system( "pause" );
               return 0;
          }

           std::cout <<" Byte --->"<< pPrintByteCoding->cByte <<"  Coding --->";
           std::list <int>:: iterator ilistBegin = pPrintByteCoding ->listByteCodes. begin();
           std::list <int>:: iterator ilistEnd    = pPrintByteCoding ->listByteCodes. end();
           for( ; ilistBegin != ilistEnd; ++ ilistBegin )
               std::cout <<(*ilistBegin);
           std::cout <<std:: endl<<std ::endl;
     }

      // g_szBuffer[nBufferSize] 编码
      // 将编码完的编码串用 list 容器存起来
      std::list <int> listBufferCodes;
      listBufferCodes.clear ();
      std::vector <SByteCoding*>:: iterator iVecFindCodes ;
      for( int i = 0; i < nBufferSize && g_szBuffer[ i] != '\0'; ++i )
     {
           char cByte = g_szBuffer[ i];  // SFindByteFormCodings
           iVecFindCodes = std ::find_if( vecByteCoding .begin(), vecByteCoding.end (), SFindByteFormCodings ( cByte ) );
           if( iVecFindCodes == vecByteCoding. end() )
          {
               std::cout <<"Error 11"<<std ::endl;
               system( "pause" );
               return 0;
          }
           std::list <int>:: iterator ilistBegin = (*iVecFindCodes )->listByteCodes. begin();
           std::list <int>:: iterator ilistEnd    = (*iVecFindCodes )->listByteCodes. end();
           for( ; ilistBegin != ilistEnd; ++ ilistBegin )
               listBufferCodes.push_back ( (*ilistBegin) );
     }

      // PrintCodes( listBufferCodes );
      std::cout <<g_szBuffer<< " 编码: " ;
      std::list <int>:: iterator ilistPrintCodesBegin = listBufferCodes .begin();
      std::list <int>:: iterator ilistPrintCodesEnd    = listBufferCodes .end();
      for( ; ilistPrintCodesBegin != ilistPrintCodesEnd; ++ilistPrintCodesBegin )
           std::cout <<(*ilistPrintCodesBegin);
      std::cout <<std:: endl;
     
      // 解码
      std::vector <char> vecDecodeStr;
      vecDecodeStr.clear ();

      ilistPrintCodesBegin = listBufferCodes. begin();
      ilistPrintCodesEnd   = listBufferCodes .end();
      SBinaryTreeNode* pFindNode = pBinaryTreeRoot;
      for( ; ilistPrintCodesBegin != ilistPrintCodesEnd; ++ilistPrintCodesBegin )
     {
           int nTag = (*ilistPrintCodesBegin);

           if( TREE_TAG_LEFT == nTag )
          {
               pFindNode = pFindNode ->pLeftChild;
          }
           else
               pFindNode = pFindNode ->pRightChild;

           if( pFindNode ->cByte != 0 )
          {
               char cNewByte = pFindNode-> cByte;
              
               vecDecodeStr.push_back ( cNewByte );
               pFindNode = pBinaryTreeRoot ;
          }
     }

      // 输出解码
      std::cout <<std:: endl<<" 解码 : ";
      std::vector <char>:: iterator iVecCharBegin = vecDecodeStr .begin();
      std::vector <char>:: iterator iVecCharEnd    = vecDecodeStr .end();
      for( ; iVecCharBegin != iVecCharEnd; ++ iVecCharBegin )
           std::cout <<(*iVecCharBegin);
      std::cout <<std:: endl;

      system("pause" );
      return 0;
}
原创粉丝点击