【問題描述】
利用哈夫曼編碼進行通訊可以大大提高通道利用率,縮簡訊息傳輸時間,降低傳輸成本。但是,這要求發送端通過一個編碼系統對資料進行編碼,在接受端將傳來的資料進行解碼。試為這樣的資訊收發站寫一個哈夫曼編碼/解碼系統。
【基本要求】
本系統應實現以下功能:(功能1~3必做,4為選做,請課後自行完成)
(1) 初始化:字元集(字母a~z,空格)共27個字元,以及其權值。建立哈夫曼樹。並建立各個字元的哈夫曼編碼。
(2) 列印字元集的哈夫曼編碼。
(3) 編碼:從終端讀入字串,實現該字串的編碼。
(4) 解碼:實現剛才產生的哈夫曼編碼還原為字串。(選做)
#include <iostream>#include <string.h>using namespace std;#define N 50/*葉子結點數*/#define M 2*N-1/*樹中結點總數*/typedef struct{char data;/*結點值*/int weight;/*權重*/int parent;/*雙親結點*/int lchild;/*左孩子結點*/int rchild;/*右孩子結點*/} HTNode;typedef struct{char cd[N];/*存放哈夫曼碼*/int start;} HCode;void CreateHT(HTNode ht[],int n){/*建立哈夫曼樹*/int i, j, k, lnode, rnode;double min1, min2;for(i = 0 ; i < 2*n-1 ; i++)ht[i].parent = ht[i].lchild = ht[i].rchild = -1;for(i = n ; i < 2*n-1 ; i++){min1 = min2 = 32767;lnode = rnode = -1;for(k = 0; k <= i - 1 ; k++)if(ht[k].parent == -1){if( ht[k].weight < min1){min2 = min1; rnode = lnode;min1 = ht[k].weight; lnode = k;}else if(ht[k].weight < min2){min2 = ht[k].weight; rnode = k;}}ht[i].weight = ht[lnode].weight + ht[rnode].weight;ht[i].lchild = lnode; ht[i].rchild = rnode;ht[lnode].parent = i; ht[rnode].parent = i;}}void CreateHCode(HTNode ht[],HCode hcd[],int n){ /*建立哈夫曼編碼*/int i, f, c;HCode hc;for(i = 0; i < n; i++){hc.start = n; c = i;f = ht[i].parent;while(f != -1){if(ht[f].lchild == c)hc.cd[hc.start--] = '0';else hc.cd[hc.start--] = '1';c = f; f=ht[f].parent;}hc.start++;hcd[i] = hc;}}void DispHCode(HTNode ht[],HCode hcd[],int n){/*顯示各個字元的哈夫曼編碼*/int i,k; int sum=0,m=0,j; cout<<"該字元集的哈夫曼編碼如下: "<<endl; for(i=0;i<n;i++){ j=0; cout<<ht[i].data<<" "; for(k=hcd[i].start;k<=n;k++){ cout<<hcd[i].cd[k]; } printf("\n"); }}void Encode(char *s,HTNode ht[],HCode hcd[],int n){ /*顯示字串s的哈夫曼編碼*/int i, j, k;for(i = 0; s[i] != '\0'; i++)cout<<s[i];cout<<"的哈夫曼編碼是: "<<endl; i = j =0;while(s[j] != '\0'){if(s[j] == ht[i].data){for(k = hcd[i].start; k <= n; k++)cout<<hcd[i].cd[k];j++;i = 0;} elsei++;}cout<<endl;}int main(){int n = 27,i;char s[100];char str[]={' ','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'}; /*字元集*/int fnum[]={186,64,13,22,32,103,21,15,47,57,1,5,32,20,57,63,15,1,48,51,80,23,8,18,1,16,1}; /*字元集對應的權值*/HTNode ht[M];HCode hcd[N];for (i = 0 ; i < n ; i++){ ht[i].data = str[i]; ht[i].weight = fnum[i]; } CreateHT(ht,n);CreateHCode(ht,hcd,n);DispHCode(ht,hcd,n);cout<<endl<<endl<<"請輸入字串: ";gets(s);Encode(s,ht,hcd,n);return 0; }