霍夫曼編碼解碼

來源:互聯網
上載者:User
#include <iostream>#include <cstring>using namespace std;#define MAX 32767 typedef struct{    int weight;    char value;    int parent;    int lchild;    int rchild;}HTNode, *HuffmanTree;        //動態分配數組儲存霍夫曼樹typedef struct{     char * HfmCode;            //動態分配數組,儲存哈夫曼編碼    char value; }code, *HuffmanCode; //選擇最小權重的兩個樹void select(HuffmanTree &ht,int n,int *s1,int *s2)    {    /*ht,為樹所在數組的頭指標,n為允許尋找的最大序號,s1,s2,返回最小的兩個序號*/    int p1=MAX;     int p2=MAX;         /*p1, p2用來記錄最小的兩個權, 要求p1<p2*/    int pn1=0;     int pn2=0;        /*pn1, pn2 用來記錄這兩個權的序號*/    int i;    for(i=1;i<=n;i++)    {        if(ht[i].weight<p1 && ht[i].parent==0)    //ht[i].parent=0的作用是去掉已經選過的節點        {            pn2=pn1;            p2=p1;            pn1=i;            p1=ht[i].weight;        }        else if(ht[i].weight<p2 && ht[i].parent==0)        {            pn2=i;            p2=ht[i].weight;        }    }    *s1=pn1;    //賦值返回    *s2=pn2;    }//建立霍夫曼樹void Creat_HuffmanTree(HuffmanTree &ht,int *w,char *st,int n){    int m=2*n-1;    ht=(HuffmanTree)malloc( (m+1)*sizeof(HTNode) );        //0號單元不用    HuffmanTree p;    int i;    w=w+1;    //因為w[]的0號單元沒有用    st=st+1;    for(p=ht+1,i=1; i<=n; i++,p++,w++,st++ )        //1-n號放葉子結點,初始化    {        (*p).weight=*w;        (*p).value=*st;        (*p).parent=0;        (*p).lchild=0;        (*p).rchild=0;    }    for(; i<=m; i++,p++)        //非葉子結點初始化    {        (*p).weight=0;        (*p).parent=0;        (*p).lchild=0;        (*p).rchild=0;    }    int s1,s2;    //在select函數中使用,用來儲存最小權的結點的序號    for(i=n+1;i<=m;++i)        //建立非葉子結點,建哈夫曼樹    {        //在ht[1]~ht[i-1]的範圍內選擇兩個parent為0且weight最小的結點,其序號分別賦值給s1、s2返回        select(ht,i-1,&s1,&s2);         ht[s1].parent=i;        ht[s2].parent=i;        ht[i].lchild=s1;        ht[i].rchild=s2;        ht[i].weight=ht[s1].weight + ht[s2].weight;    }}//哈夫曼樹建立完畢//輸出所有節點權重void outputHuffman(HuffmanTree &ht, int m) {     for(int i=1;i<=m;i++)        cout<<ht[i].weight<<" ";} //從葉子結點到根,逆向求每個葉子結點對應的哈夫曼編碼void Creat_HuffmanCode(HuffmanTree &ht,HuffmanCode &hc,int n){    char *cd;    int start;    int c;    //c指向當前節點    int p;    //p指向當前節點的雙親結點    int i;    hc=(HuffmanCode)malloc( (n+1)*sizeof(code) );    //分配n個編碼的頭指標    cd=(char * )malloc(n * sizeof(char ));    //分配求當前編碼的工作空間    cd[n-1]='\0';    //從右向左逐位存放編碼,首先存放編碼結束符    for(i=1;i<=n;i++)    //求n個葉子結點對應的哈夫曼編碼    {        hc[i].value=ht[i].value;        start=n-1;        //初始化編碼起始指標        for(c=i,p=ht[i].parent; p!=0; c=p,p=ht[p].parent)    //從葉子到根結點求編碼        {            if(ht[p].lchild == c)                cd[--start]='0';            else                cd[--start]='1';        }        hc[i].HfmCode = (char *)malloc(n*sizeof(char));    //為第i個編碼分配空間        strcpy(hc[i].HfmCode,&cd[start]);    }    free(cd);}//解碼void Decoding_HuffmanTree(HuffmanTree &ht,char code[],char result[]){    int i , k=0 ;    int p=0, root;       for (root=1 ; ht[root].parent!=0 ; root=ht[root].parent)        ;  //root是霍夫曼樹的根     for (i=0 , p=root ; code[i]!='\0'; i++)       {           if (code[i] == '0')               p = ht[p].lchild;           else              p = ht[p].rchild;           if (ht[p].lchild==NULL && ht[p].rchild==NULL)           {               result[k++] = ht[p].value;               p = root;         }       }        result[k] = '\0';   }int main(){    HuffmanTree        HT;    HuffmanCode        HC;    int *w;        //動態數組,存放各字元的權重    char *st;    //字串,存放節點的值    int i,n;    //n is the number of elements    int m;    cout<<"input the total number of the Huffman Tree:"<<endl;     cin>>n;    w=(int *)malloc( (n+1)*sizeof(int) );        //0號單元不用    st=(char *)malloc( (n+1)*sizeof(char) );    //0號單元不用    FILE *fin=fopen("哈弗曼編碼.txt","r");      for(i=1;i<=n;i++)    {        fscanf(fin,"%c%d",&st[i],&w[i]);    }        Creat_HuffmanTree(HT,w,st,n); /*構造H樹*/        m=2*n-1;    outputHuffman(HT,m);    /*顯示H樹*/    cout<<endl;    Creat_HuffmanCode(HT,HC,n); /*根據H樹,求每個字元的編碼,放在HC中*/    for(i=1;i<=n;i++)        /*輸出編碼*/         cout<<HC[i].value<<"  "<<HC[i].HfmCode<<endl;         //解碼    char *code="01101110101010001110110110011100";    char *result;    result=(char *)malloc(100*sizeof(char));    Decoding_HuffmanTree(HT,code,result);    //result[]存放解碼結果    for(i=0;result[i];i++)         cout<<result[i]<<"  ";     return 0;}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.