赫夫曼樹與赫夫曼編碼

2021-04-12 12:49:06 字數 2941 閱讀 7347

【問題描述】

利用huffman編碼進行通訊可以大大提高通道利用率,縮短資訊傳輸時間,降低傳輸成本。但是,這要求在傳送端通過乙個編碼系統對待傳資料預先編碼,在接受端將傳來的資料編碼進行解碼(復原)。對於有些通道,每端都需要乙個完整的編/解碼系統。試為這樣的資訊收發站編寫乙個huffman的編/解碼系統。給定一組權值,構造一棵赫夫曼樹,並計算帶權路徑長度wpl。

【資料描述】

//- - - - - 赫夫曼樹的儲存表示 - - - - -

typedef struct htnode;    //用順序儲存結構表示赫夫曼樹的結點結構定義

//動態分配陣列儲存huffman編碼表

【演算法描述】

1.初始化:從鍵盤讀入n個字元,以及它們的權值,建立huffman樹

2.編碼:根據建立的huffman樹,求每個字元的huffman編碼。對給定的待編碼字串行進行編碼。

3.解碼:利用已經建立好的huffman樹,對上面的編碼結果解碼。解碼的過程是分解電文中的字串,從根結點出發,按字元』0』和』1』確定找左孩子或右孩子,直至葉結點,便求得該子串相應的字元。

4.列印 huffman樹。

【c源程式】

/*實現初始化,建立huffman樹,並完成字元的編碼*/

#include

#define n 10     /*待編碼字元的個數,即樹中葉結點的最大個數*/

#define m 2*n-1  /*樹中總的結點數目*/

typedef structhtnode;  /*樹中結點的結構*/

typedef struct htcode;

void init(htcode hc,int *n){

/*初始化,讀入待編碼字元的個數n,從鍵盤輸入n個字元和n個權值*/

int i;

printf("/ninput n=");

scanf("%d",&(*n));

printf("/ninput %d character/n",*n);

for (i=1;i<=*n;i++) hc[i].data=getch();

printf("/ninput %d weight/n",*n);

for (i=1;i<=*n;i++) scanf("%d",&(hc[i].weight));

void select(htnode ht,int k,int *s1,int *s2){

/*ht[1…k]中選擇parent為0,並且weight最小的兩個結點

其序號由指標變數s1,s2指向*/

int i;

for (i=1;i<=k && ht[i].parent!=0 ;i++);

*s1=i;

for (i=1;i<=k;i++)

if (ht[i].parent==0 && ht[i].weightfor (i=1; i<=k ; i++)

if (ht[i].parent==0 && i!=*s1) break;

*s2=i;

for (i=1;i<=k;i++)

if ( ht[i].parent==0 && i!=*s1 && ht[i].weightvoid huffmancoding(htnode ht,htcode hc,int n){

/*構造huffman樹ht,並求出n個字元的編碼*/

char cd[n];

int i,j,m,c,f,s1,s2,start;

m=2*n-1;

for (i=1;i<=m;i++){

if (i<=n)  ht[i].weight=hc[i].weight;

else ht[i].weight=0;

ht[i].parent=ht[i].lchild=ht[i].rchild=0;

for (i=n+1;i<=m;i++){

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;

cd[n-1]='/0';

for (i=1;i<=n;i++) {

start=n-1;

for (c=i,f=ht[i].parent;f;c=f,f=ht[f].parent)

if (ht[f].lchild==c) cd[--start]='0';

else cd[--start]='1';

strcpy(hc[i].code,&cd[start]);

main(){

int i,m,n,w[n+1];

htnode ht[m+1];

htcode hc[n+1];

init(hc,&n);           /*初始化*/

huffmancoding(ht,hc,n);/*構造huffman樹,並形成字元的編碼*/

/*輸出字元的編碼*/

for (i=1;i<=n;i++)printf("/n%c --- %s",hc[i].data,hc[i].code);

【測試資料】

1. 根據執行提示,依次輸入待編碼的字元個數和這些字元,以及每個字元的權值:

input n=4↙

input 4character       

abcd↙

input4 weight       

7 5 2 4↙

輸出:a --- 0

b --- 10

c --- 110

d --- 111

2.可根據執行提示,自行指定資料,觀察程式的執行結果。

【說明】

此處只是huffman樹的建立和編碼演算法的實現,乙個完整的huffman編/解碼系統應進一步完善,實現以上演算法描述的四個基本要求,並可考慮將hufmman樹和huffman編碼存在磁碟檔案中。

赫夫曼樹與赫夫曼編碼

赫夫曼樹又稱為最優二叉樹。帶權路徑長度wpl最小的二叉樹稱為最優二叉樹。從樹根結點到該結點之間的路徑長度與該結點上權的乘積稱為結點的帶權路徑長度,樹中所有葉子結點的帶權路徑長度之和稱為該樹的帶權路徑長度 wpl 通常記為 赫夫曼 huffman 樹的特徵 當葉子上的權值均相同時,完全二叉樹一定是最優...

赫夫曼樹與赫夫曼編碼

時間限制 1 sec 記憶體限制 128 mb 輸入 輸入包含多組資料 不超過100組 每組資料第一行乙個整數n,表示字元個數。接下來n行,每行有乙個字元ch和乙個整數weight,表示字元ch所對應的權值,中間用空格隔開。輸入資料保證每組測試資料的字元不會重複。輸出 對於每組測試資料,按照輸入順序...

赫夫曼樹和赫夫曼編碼

赫夫曼樹 1 先把有權值的葉子節點按照從小到大的順序排成乙個有序序列,即 a 5 e 10 b 15 d 30 c 40 2 取前兩個權值最小的結點即a 5 和e 10 作為乙個新的結點n1的兩個子節點,結點權值較小的作為左結點,即a為左結點,e為右結點,n1的權值為兩個結點權值的和,即5 10 1...