今天介紹一下哈弗曼編碼與解碼。
什麼是哈夫曼編碼?怎麼進行哈弗曼編碼?以及進行哈夫曼編碼以後怎麼進行解碼工做呢?表急,接下來我會簡單介紹一下。
===========================================如下來自我老師的PPT課件====================================================
哈夫曼編碼可以使一般的數據傳輸數量減小到最小。這個編碼的發明和這個算法同樣十分引人入勝。他的算法也普遍應用於傳真機,圖象壓縮和計算機安全領域。
哈夫曼樹的特色:
至於哈夫曼樹的構造方法:就是把結點的權值按照從小往大依次向上進行合併,如圖:(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++