哈夫曼編碼譯碼系統(c/c++)


哈夫曼編碼譯碼系統的實現,主要包含三部分:

1、創建哈夫曼樹

2、編碼函數

3、譯碼函數

編寫代碼時為了方便,在這里混用了c++的輸入輸出流。主體用c語言實現。

下面時代碼部分:

1、頭文件,以及儲存結構:

#include<stdio.h>
#include<iostream>
using namespace std;
#define MAX 2000
typedef char ElemType;
typedef struct{
ElemType data;
int w;
int parent,lchild,rchild;
}HFMTNode;

2、哈夫曼樹的創建,Ht儲存全部節點的權值,n代表葉子節點數量。

void menu(HFMTNode Ht [],int n);//原型聲明 
void CreatHFMTree(HFMTNode Ht[],int n)//創建哈夫曼樹 
{
    int i,j,k,lmin,rmin;
    int min1,min2,m1;
    for(i=1;i<2*n;i++)
    {
        Ht[i].parent=Ht[i].lchild=Ht[i].rchild=-1;
    }
    for(i=n+1;i<2*n;i++)
    {
        min1=min2=MAX;
        lmin=rmin=-1;
        for(k=1;k<i;k++)
        {
            if(Ht[k].parent==-1)//只在尚未構造的二叉樹節點中運行 
            {
                if(Ht[k].w<min1)
                {
                    min2=min1;
                    rmin=lmin;
                    min1=Ht[k].w;
                    lmin=k;
                }
                else
                 {
                    if(Ht[k].w<min2)
                    {
                        min2=Ht[k].w;
                        rmin=k;
                    }
                }
            }
            else{ 
                if(Ht[k].w<min2&&k>m1)//與創建好的二叉樹節點比較,選取w小的一個 
                {
                    min2=Ht[k].w;
                    rmin=k;
                    m1=k;
                }
            }
        }
        Ht[lmin].parent=i;//對選擇出的結點進行連接 
        Ht[rmin].parent=i;
        Ht[i].w=Ht[lmin].w+Ht[rmin].w;
        Ht[i].lchild=lmin;
        Ht[i].rchild=rmin;
    }
    printf("HFMTree have been created\n");
 } 

3、編碼譯碼函數、主函數:

 void encoding(HFMTNode Ht [],int n)//編碼 
 {
     int k;
     fflush(stdin);
     printf("Please input what you want to encode with the ending of'#' :\n");
     char ch;
     ch=getchar();                      //讀取字符 
     while (ch!='#')
     {
         for(k=1;k<=n;k++)
         {
             if(Ht[k].data==ch)
             {
                 break;
             }
         }                           //找到字符位置 
         HFMTNode temp1,temp=Ht[k];
         int flag=0;
         int a[n];
         while(temp.w!=Ht[2*n-1].w)
         {
             temp1=temp;
             temp=Ht[temp.parent];
             if(Ht[temp.lchild].w==temp1.w )
             {
                 a[flag]=0;
                 flag++;
             }
             else if(Ht[temp.rchild].w==temp1.w )
             {
                 a[flag]=1;
                 flag++;
             }
          }                               //用數組記錄路徑 
          for(int f=flag-1;f>=0;f--)
          {
              printf("%d",a[f]);
          }                                //編碼輸出 
         ch=getchar();
     }
     printf("\nencoding have finished\n");
    system("pause");
    system("cls");
    menu(Ht,n);
 }
 void decoding(HFMTNode Ht [],int n)//譯碼 
 {
     int k=2*n-1;
     fflush(stdin);
     printf("Please input what you want to decode with the ending of'#' :\n");
     char ch;
     ch=getchar();                      //依次讀取01字符 
     HFMTNode temp=Ht[2*n-1];
     while (ch!='#')
    {
        if(ch=='1')
        {
            if(temp.rchild==-1)
            {
                printf("%c",temp.data);           //根據01向左右尋找,到達葉子節點時輸出 
                temp=Ht[2*n-1];
                continue;
            }
            else
            {
                temp=Ht[temp.rchild ];
                ch=getchar();
            }
        }
        else if(ch=='0')
        {
            if(temp.lchild==-1)
            {
                printf("%c",temp.data);
                temp=Ht[2*n-1];
                continue;
            }
            else
            {
                temp=Ht[temp.lchild ];
                ch=getchar();
            }
        }
    }
    printf("%c",temp.data);                    //輸出要譯碼的最后一個字符 
    printf("\ndecoding have finished\n");
    system("pause");
    system("cls");
    menu(Ht,n);
 }
 void menu(HFMTNode Ht [],int n)
 {
     int j;
     printf("Input your choice:\n");
     printf("1.encoding      2.decoding      0.exit\n");
     cin>>j;
     switch (j)
     {
         case 1:encoding(Ht,n);break;
         case 2:decoding(Ht,n);break;
         case 0:break;
     } 
 }
 int main()
 {
     printf("Please input the amount of the node:\n");
     int i;
     scanf("%d",&i);
     HFMTNode Ht[2*i];//儲存各個節點的數據 
     for(int k=1;k<=i;k++)
     {
         printf("Ht[%d]:Please input data :",k);
         cin>>Ht[k].data;
         printf("Ht[%d]:Please input w :",k);
         cin>>Ht[k].w;
     }
     CreatHFMTree(Ht,i);
     menu(Ht,i);
     return 0;
 }

       上面代碼放在一起即可直接運行,本人水平有限,如有錯誤,歡迎大神指正。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM