哈弗曼編碼與解碼

  今天介紹一下哈弗曼編碼與解碼。
什麼是哈夫曼編碼?怎麼進行哈弗曼編碼?以及進行哈夫曼編碼以後怎麼進行解碼工做呢?表急,接下來我會簡單介紹一下。
===========================================如下來自我老師的PPT課件====================================================
哈夫曼編碼可以使一般的數據傳輸數量減小到最小。這個編碼的發明和這個算法同樣十分引人入勝。他的算法也普遍應用於傳真機,圖象壓縮和計算機安全領域。
      哈夫曼樹:帶權路徑長度最小的二叉樹,亦稱最優二叉樹。
  哈夫曼樹的特色: 
      一、權值越大的葉子結點越靠近根結點,而權值越小的葉子結點越遠離根結點。(構造哈夫曼樹的核心思想)
      二、只有度爲0(葉子結點)和度爲2(分支結點)的結點,不存在度爲1的結點。
      三、n個葉結點的哈夫曼樹的結點總數爲2n-1個。
      四、哈夫曼樹不惟一,但WPL惟一。
   ===============================讓yogurt偷個懶,嘿嘿嘿========================================
 
至於哈夫曼樹的構造方法:就是把結點的權值按照從小往大依次向上進行合併,如圖:(yogurt的字有點醜~~~~(>_<)~~~~你們將就看看就好哈)

編碼方法:就是從根結點開始,根結點的左孩子編碼爲0,右孩子編碼爲1,再把左孩子結點當作根結點(右孩子結點也當作根結點),繼續編碼,直到編碼到葉子結點爲止。
從根節點直到目標結點,一路上通過的編碼就是最終的編碼啦!
你們能夠直接在代碼中看到方法的體現,接下來,上代碼:
  1 #include<stdio.h>
  2 #include<stdlib.h>
  3 #include<string.h>
  4 typedef char** HC;
  5 
  6 typedef struct Node
  7 {
  8     int weight;
  9     char character;
 10     struct Node* parent,* lchild,* rchild;
 11 }node,*huffmantree;
 12 
 13 huffmantree CreateHuffmantree(node * H, int n);
 14 HC code(huffmantree HT, int n);
 15 char decode(huffmantree HT, char * c);
 16 
 17 void main()
 18 {
 19     int w[7] = { 3,4,1,4,2,6,8 };
 20     char v[7] = { 'a', 'b', 'c', 'd', 'e', 'f', 'g' };
 21     int n = 7,i,j;
 22     node H[13];//保存每個結點,前7位是葉節點(即規定權值),後6位是分支結點
 23     for (i = 0, j = 0; i < 13; i++, j++)
 24     {
 25         if (i < 7)
 26         {
 27             H[i].weight = w[j];
 28             H[i].character = v[j];
 29         }
 30         else
 31         {
 32             H[i].weight = 0;
 33             H[i].character = ' ';
 34         }
 35         H[i].parent = 0;
 36         H[i].lchild = 0;
 37         H[i].rchild = 0;
 38     }//哈弗曼樹初始化
 39 
 40     huffmantree HT = (huffmantree)malloc(13 * sizeof(node));//分配空間
 41     HT = CreateHuffmantree(H, 13);//建立哈夫曼樹
 42     HC hc = (HC)malloc(7 * sizeof(char*));
 43     hc = code(HT,7);//編碼
 44     
 45     //驗證
 46     printf("哈夫曼編碼已完成。\n請輸入驗證字符:");
 47     char ch = getchar();
 48     for (i = 0; i < 7;i++)  //遍歷到輸入字符的編碼指針處
 49     {
 50         if (HT[i].character == ch)
 51             break;
 52     }  //求第i個字符的編碼,在hc[i]處
 53     printf("%c的哈夫曼編碼爲:", ch);
 54     puts(hc[i]);
 55     
 56     //解碼
 57     char m=decode(HT, hc[i]);
 58     printf("解碼爲:");
 59     printf("%c", m);
 60 
 61     getchar();
 62     return;
 63 }
 64 
 65 huffmantree CreateHuffmantree(node * H, int n)
 66 {
 67     int i = 7, j; 
 68     while (i < n)  //完善H的分支結點,從H[7]-H[n-1]
 69     {
 70         int min1 = 100, min2 = 100, x = 0, y = 0; //x、y分別記錄第二小和最小的元素位置
 71         for (j = 0; j <n; j++)  
 72         {
 73             if(H[j].weight>0&&H[j].parent==0)  //從已經有值且沒有parent指針的結點中找
 74             {
 75                 if (H[j].weight <min2)
 76                 {
 77                     if (H[j].weight < min1)
 78                     {
 79                         min2 = min1;
 80                         min1 =H[j].weight;
 81                         x =y;
 82                         y = j;
 83                     }
 84                     else
 85                     {
 86                         min2 = H[j].weight;
 87                         x = j;
 88                     }
 89                 }
 90             }
 91         }  //找到最小的兩個元素的位置
 92         H[i].weight =H[x].weight + H[y].weight;
 93         H[i].lchild = &H[x];
 94         H[i].rchild = &H[y];
 95         H[x].parent = &H[i];
 96         H[y].parent = &H[i];
 97         
 98         i++;
 99     }
100     return H;
101 }
102 
103 HC code(huffmantree HT, int n)
104 {
105     int i,j;
106     node * c,* f;
107     HC hc = (HC)malloc(7 * sizeof(char*));
108     for (i = 0; i < n; i++)  //爲n個字符編碼,目前爲第i個字符編碼,存放在哈弗曼樹的第i個結點上
109     {
110         j = 6;  //每次進來j都要從新變成一次6
111         hc[i] = (char*)malloc(7 * sizeof(char));
112         char a[7]; //編碼的臨時存放地
113         a[6] = '\0';
114         for (c = &HT[i], f = c->parent; f != 0; c = f, f = f->parent)
115         {
116             if ((f->lchild) == c)
117                 a[--j] = '0';
118             else
119                 a[--j] = '1';
120         }
121         strcpy(hc[i], &a[j]);
122     }
123     return hc;
124 }
125 
126 char decode(huffmantree HT, char * c)  //c是哈夫曼編碼,末尾是'\0'
127 {
128     //找到哈弗曼樹的根結點
129     int i;
130     for (i = 0; HT[i].parent != 0; i++);
131     
132     //從根結點開始往下走
133     node *n = &HT[i];
134     while (*c != '\0')
135     {
136         if (*c == '0')
137             n = n->lchild;
138         else
139             n = n->rchild;
140         c++;
141     }
142     return n->character;
143 }
 

見證奇蹟的時刻到啦!node

如此,便實現了哈夫曼編碼與解碼啦~~c++

相關文章
相關標籤/搜索