哈夫曼樹以及編譯碼

2021-07-22 14:56:16 字數 3428 閱讀 3994

這一篇要總結的是樹中的最後一種,即哈夫曼樹,我想從以下幾點對其進行總結:

1,什麼是哈夫曼樹?

2,如何構建哈夫曼樹?

3,哈夫曼編碼?

4,演算法實現?

回到頂部

什麼是哈夫曼樹呢?

哈夫曼樹是一種帶權路徑長度最短的二叉樹,也稱為最優二叉樹。下面用一幅圖來說明。

它們的帶權路徑長度分別為:

圖a: wpl=5*2+7*2+2*2+13*2=54

圖b: wpl=5*3+2*3+7*2+13*1=48

可見,圖b的帶權路徑長度較小,我們可以證明圖b就是哈夫曼樹(也稱為最優二叉樹)。

回到頂部

一般可以按下面步驟構建:

1,將所有左,右子樹都為空的作為根節點。

2,在森林中選出兩棵根節點的權值最小的樹作為一棵新樹的左,右子樹,且置新樹的附加根節點的權值為其左,右子樹上根節點的權值之和。注意,左子樹的權值應小於右子樹的權值。

3,從森林中刪除這兩棵樹,同時把新樹加入到森林中。

4,重複2,3步驟,直到森林中只有一棵樹為止,此樹便是哈夫曼樹。

下面是構建哈夫曼樹的**過程:

三,哈夫曼編碼

利用哈夫曼樹求得的用於通訊的二進位制編碼稱為哈夫曼編碼。樹中從根到每個葉子節點都有一條路徑,對路徑上的各分支約定指向左子樹的分支表示」0」碼,指向右子樹的分支表示「1」碼,取每條路徑上的「0」或「1」的序列作為各個葉子節點對應的字元編碼,即是哈夫曼編碼。

就拿上圖例子來說:

a,b,c,d對應的哈夫曼編碼分別為:111,10,110,0

用圖說明如下:

記住,設計電文總長最短的二進位制字首編碼,就是以n個字元出現的頻率作為權構造一棵哈夫曼樹,由哈夫曼樹求得的編碼就是哈夫曼編碼。

摘自

在電報通訊中,電文是以二進位制的0、1序列傳送的。字符集中的字元的使用頻率是不同的(比如e和t的使用較之q和z要頻繁得多),哈夫曼編碼可以使得編碼的總長最短,從而相同的位長可以傳送更多的資訊。

本程式以下面的字元及使用頻率為例:

字元權值

a0.12

b0.40

c0.15

d0.08

e0.25

首先建立哈夫曼樹:i0

1234

5678

tree[i].chab

cde

tree[i].weight

0.12

0.40

0.15

0.08

0.25

0.20

0.35

0.60

1.00

tree[i].parent58

6576

780tree[i].lchild

-1-1

-1-1-13

241tree[i].rchild

-1-1

-1-1-10

567

得到哈夫曼樹和哈夫曼編碼如下:

下面是哈夫曼編碼的儲存結構:

序號bits

chstart01

111a

21

0b52 11

0c33

1110

d24

10e4

程式清單如下:

#include

#define n 5  //葉子數目

#define m (2*n-1) 

//結點總數

#define maxval 10000.0

#define maxsize 100 

//哈夫曼編碼的最大位數

typedef struct

hufmtree;

typedef struct

codetype;

void huffman(hufmtree tree);//建立哈夫曼樹

void huffmancode(codetype code,hufmtree tree);//根據哈夫曼樹求出哈夫曼編碼

void decode(hufmtree tree);//依次讀入電文,根據哈夫曼樹解碼

void main()

printf("【讀入電文,並進行解碼】\n");

decode(tree);//依次讀入電文,根據哈夫曼樹解碼

}void huffman(hufmtree tree)//建立哈夫曼樹

printf("【依次讀入前%d個結點的字元及權值(中間用空格隔開)】\n",n);

for(i=0;i //讀入前n個結點的字元及權值

for(i=n;i

//進行n-1次合併,產生n-1個新結點

else

if(tree[j].weight

tree[p1].parent=i;

tree[p2].parent=i;

tree[i].lchild=p1;  //最小權根結點是新結點的左孩子

tree[i].rchild=p2;  //次小權根結點是新結點的右孩子

tree[i].weight=tree[p1].weight+tree[p2].weight;

}}//huffman

void huffmancode(codetype code,hufmtree tree)//根據哈夫曼樹求出哈夫曼編碼

//codetype code為求出的哈夫曼編碼

//hufmtree tree為已知的哈夫曼樹

code[i]=cd; 

//第i+1個字元的編碼存入code[i]

}}//huffmancode

void decode(hufmtree tree)//依次讀入電文,根據哈夫曼樹解碼

j++;

}printf("\n");

if(tree[i].lchild!=-1&&b[j]!='2') 

//電文讀完,但尚未到葉子結點

printf("\nerror\n");  //輸入電文有錯

}//decode

貼出一例執行結果:

摘自

哈夫曼樹編 解碼演算法

一 實驗目的 掌握哈弗曼編 解碼演算法。1.掌握huffman 樹的概念 特點和儲存結構 2.掌握huffman 樹的構造方法 3.學會靈活運用huffman 樹解決編碼問題。4.問題描述 5.某報文中共出現n個字元,各字元出現頻度依次為w1,w2,wn。要求設計乙個不等長的編碼方案,輸出每個字元對...

哈夫曼樹建立和解碼

題目描述 假設某通訊報文的字符集由a,b,c,d,e,f這6個字元組成,它們在報文 現的頻度 頻度均為整數值 1 構造一棵哈弗曼樹,依次給出各字元編碼結果。2 給字串進行編碼。3 給編碼串進行解碼。規定 構建哈弗曼樹時 左子樹根結點權值小於等於右子樹根結點權值。生成編碼時 左分支標0,右分支標1。輸...

哈夫曼樹的建立以及哈夫曼編碼

主要源 如下 include include define max num 105 typedef struct htnode,htree void selecttwomin htree ht,int n,int s1,int s2 ht s1 visited 1 將最小的頻率對應的結點標記為已被訪...