哈夫曼编码的设计与实现

#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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值