演算法學習-哈夫曼編碼(c++實現),哈夫曼

來源:互聯網
上載者:User

演算法學習-哈夫曼編碼(c++實現),哈夫曼
哈夫曼編碼

哈夫曼編碼雖然簡單,但是是一個非常重要的編碼方式,它解決了資料存放區的一個非常重要的問題:壓縮!它的編碼方式是最優的,無損的,尤其在映像中使用的非常多。下面講下它的原理。

編碼方式

哈夫曼編碼的構造是依據權值的大小來實現的。首先根據權值構造哈夫曼樹,然後對哈夫曼樹進行逆向遍曆,從而找到每個節點的編碼方式。

例如:
abbcccdddde這個是一個字串,一共有5個字元。每個字元的權值就是出現的頻率,那麼a就是1b權值為2c的權值為3d的權值為4e的權值為1。在普通的編碼方式中,表示5個字母最少要3位,也就是3bit.那麼這串字元就需要1*3+2*3+3*3+4*3+1*3=33 bits。而使用哈夫曼的編碼呢?

構造哈夫曼樹的流程是每次找到權值最小的兩個,放到一起,組成一顆樹,根節點是權值的和。
第一步:

       2        / \     1   1

這樣權值為1的ae就已經構造完了。並且把當前的2放回權值列表,下面最小的兩個是這個2b的權值2

           4         /   \        2     2       /  \      1    1

這樣第二步就構造完了,再把4放回權值列表,繼續找,依次類推

      ...省略ing

結果的哈夫曼樹: 

                     11                  /       \                 7         4                 /  \       / \                3    4     2   2                        / \                       1   1

好,這就是最終的哈夫曼樹。看見沒有~ 每個葉子節點,都代表了一個字元,1就是ae的。2b的,依次...省略ing

然後遍曆,左就是0,右就是1
c的就是00d的就是01,a的是100,b=11,e=101.這樣就成功了。

下面驗證成果:計算儲存空間。從ae:3*1+2*2+2*3+2*4+3*1 = 24 bits。發現沒,少了整整9 bits,什麼概念?也就是說壓縮了接近1/3啊,假如3G大小,壓縮後就是2G了啊。
既然這麼好,下面附上代碼實現。

代碼實現

</pre><pre name="code" class="cpp">////  main.cpp//  HuffmanCode////  Created by Alps on 14/11/22.//  Copyright (c) 2014年 chen. All rights reserved.//#include <iostream>using namespace std;typedef struct HTNode{    int weight;    int parent;    int lchild;    int rchild;}HTNode, *HuffmanTree;typedef char** HuffmanCode;void Select(HuffmanTree HT, int num, int &child1, int &child2);void HuffmanCoding(HuffmanTree &HT, HuffmanCode &HC, int *w, int n){    //    int m,i;    int child1,child2;    if (n <= 1) {        return;    }    m = n*2-1;//整棵樹的節點數    HT = (HuffmanTree)malloc((m+1) * sizeof(HTNode));//申請足夠空間    for (i = 1; i <= n; i++,w++) {        HT[i] = {*w, 0, 0, 0};    }    for (; i <= m; i++) {        HT[i] = {0, 0, 0, 0};    }    for (i = n+1; i <= m; i++) {        Select(HT,i-1,child1,child2);        HT[child1].parent = i;        HT[child2].parent = i;        HT[i].lchild = child1;        HT[i].rchild = child2;        HT[i].weight = HT[child1].weight + HT[child2].weight;        printf("%d==%d\n",child1,child2);    }        HC = (char**)malloc((n+1)*sizeof(char *));        char *cd = (char*)malloc(n*sizeof(char));//    memset(cd, '\0', n*sizeof(char));    int c = 0;        int tempParent,count;    for (i = 1; i <= n; i++) {        count = 0;        for (c = i,tempParent = HT[i].parent; tempParent != 0;c=tempParent, tempParent = HT[tempParent].parent) {            if (HT[tempParent].lchild == c) {                cd[count++] = '0';            }else{                cd[count++] = '1';            }        }        cd[count]='\0';        printf("%s~%d\n",cd,i);        HC[i] = (char *)malloc((count)*sizeof(char));        for (int j = count; j>=0; j--) {            HC[i][count-j] = cd[j-1];        }//        memset(cd,'\0', n*sizeof(char));//error    }}void Select(HuffmanTree HT, int num, int &child1, int &child2){    child1 = 0;    child2 = 0;    int w1 = 0;    int w2 = 0;    for (int i = 1; i <= num; i++) {        if (HT[i].parent == 0) {            if (child1 == 0) {                child1 = i;                w1 = HT[i].weight;                continue;            }            if (child2 == 0) {                child2 = i;                w2 = HT[i].weight;                continue;            }            if (w1 > w2 && w1 > HT[i].weight) {                w1 = HT[i].weight;                child1 = i;                continue;            }            if (w2 > w1 && w2 > HT[i].weight) {                w2 = HT[i].weight;                child2 = i;                continue;            }        }    }}int main(int argc, const char * argv[]) {    char a[] = "abcaab";    int i = (int)strlen(a);    printf("%d\n",i);        int b[]={1,2,3,4};    HuffmanTree HT;    HuffmanCode HC;    HuffmanCoding(HT, HC, b, 4);    for (i = 1; i <= 7; i++) {        printf("%d-%d\n",HT[i].weight,HT[i].parent);    }    for (i = 1; i <=4; i++) {        printf("%s\n",HC[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.