二.赫夫曼編碼
三.**實現
首先,我們得了解一下幾個概念:
路徑
:乙個結點到另乙個結點之間的路徑。
路徑長度
:路徑上的分支數目叫路徑長度
。
帶權路徑長度
:所有葉子結點的帶權路徑長度之和。
如下圖,該樹的路徑長度是:1+2+3+3=9
而帶權路徑則是:1*7+2*5+3+2+3*4=35
那麼,我們如何構造一棵赫夫曼樹呢?不難得出,肯定是權越大的結點,它的路徑長度應該最短。按以下步驟:
根據權值,將每個結點記作一棵樹,記為f1 · · ·fn,它的左右兒子皆為空,值為它的權。
將這n棵中,選兩個最小的樹,構成一棵新的樹,該樹的左右兒子為這兩個結點,該樹的值為這兩個結點權的和。並在n棵樹中,刪掉這兩顆樹,並新增構造出來的新樹。
重複2這個動作,直到只剩下一棵樹。該樹即為我們的赫夫曼樹。
在我們通訊中,資訊幾乎全是以二進位制編碼的形式傳送。假設我們對abcd
進行編碼,有00 01 10 11
這樣編碼。但如果為了降低傳輸延遲和資源,我們可以對編碼的位數進行限制,將abcd
編碼為0 00 1 01
,這樣就可以少幾位。但是這樣會出現乙個問題,假設我們收到了0000
,那麼這串編碼就會出現歧義,我們可以理解為aba、baa、aab、aaaa、bb
。所以我們需要一種任意乙個字元的編碼都不是另乙個字元的編碼的字首
,這種編碼稱為字首編碼
。
此時,赫夫曼編碼
出現惹。
我們將一顆赫夫曼樹的左兒子
規定為0,右兒子
規定為1,那麼一顆赫夫曼樹,可以完成乙個編碼:
此時,如果我們能夠統計每個字元的出現頻率,並按頻率作為這個字元的權,那麼通過構造這些字元的赫夫曼樹,就可以實現最短字首編碼
。
// 為了在尋找最小結點的時候
//只用一次遍歷就找到最小的兩個
//採用雙向鍊錶的方式比較好儲存
tnode *
treeinit
(void);
inttreelistshow
(tnode *list)
;tnode *
treemake
(tnode *list)
;int
hcodeshow
(tnode *root,
int deep)
;int hfcode[
100]=;
// 用於存放赫夫曼編碼的陣列
char hfstr[
100]=;
// 用於存放值與權重對應的hash陣列
intmain()
tnode *
treeinit
(void
)return list;
}int
treelistshow
(tnode *list)
printf
("\n");
return ok;
}tnode *
treemake
(tnode *list)
else
if(thisnode->weight < min->weight)
// 如果該結點小於次小結點而大於最小結點
thisnode = thisnode->next;
// 更新遍歷指標
}// 一次迴圈完後,應該存在最小 次小值
// 刪掉最小結點
pre = mmin->front;
pos = mmin->next;
pre->next = pos;
// 要考慮最小結點是否是最後乙個 否則會越界
if(pos !=
null
) pos->front = pre;
// 同理刪掉次小結點
pre = min->front;
pos = min->next;
pre->next = pos;
if(pos !=
null
) pos->front = pre;
// 生成新結點
newnode =
(tnode*
)malloc
(sizeof
(tnode));
newnode->lc = mmin;
newnode->rc = min;
newnode->weight = mmin->weight + min->weight;
// 把新結點插入到第乙個結點
pos = list->next;
list->next = newnode;
newnode->front = list;
newnode->next = pos;
// 也要考慮是否為最後乙個結點
if(pos !=
null
) pos->front = newnode;
// 取消注釋下面這句話,就可以看到每次迭代後的效果
//treelistshow(list);
}return list->next;
}int
hcodeshow
(tnode *root,
int deep)
// 右結點非空,遍歷
if(root->rc !=
null)}
else
}}
資料結構 赫夫曼樹
赫夫曼樹 huffman tree 又稱為最優樹,是一類帶權路徑長度最短的樹。本文僅討論最優二叉樹。樹的路徑長度是指從樹根到樹中其餘各個結點的路徑長度之和。對具有n個結點的二叉樹而言,完全二叉樹具有最短的樹的路徑長度。若在二叉樹中,樹葉結點帶有權值,則有 結點的帶權路徑長度定義為從樹根到該結點之間的...
資料結構 赫夫曼樹
赫夫曼編碼是首個試用的編碼方案。屬於無失真壓縮的編碼方案。在資料通訊中,赫夫曼編碼可以根據字元出現頻率,構造出一種不等長的二進位制,使編碼後的電文長度最短,且不產生二義性。weighteed path length是樹中所有節點的帶權路徑長度之和。wpl 值越小,說明構造出來的二叉樹效能越優。赫夫曼...
資料結構與演算法 赫夫曼樹
給定n個權值作為n個葉子結點,構造一棵二叉樹,若該樹的帶權路徑長度 wpl 達到最小,稱這樣的二叉樹為最優二叉樹,也稱為哈夫曼樹 huffman tree 還有的書翻譯為霍夫曼樹。赫夫曼樹是帶權路徑長度最短的樹,權值較大的結點離根較近。在一棵樹中,從乙個結點往下可以達到的孩子或孫子結點之間的通路,稱...