霍夫曼編碼

2021-06-27 23:44:02 字數 1880 閱讀 2329

一:八卦

在《演算法為什麼這麼難?》這篇部落格裡,劉未鵬講了乙個八卦:

根據wikipedia的介紹,霍夫曼同學(當年還在讀ph.d,所以的確是「同學」,而這個問題是坑爹的導師robert m. fano

給他們作為大作業的

,fano自己和shannon合作給出了乙個suboptimal的編碼方案,為得不到optimal的方案而寢食難安,情急之下便死馬當活馬醫扔給他的學生們了)當年為這個問題憔悴了乙個學期,最後就快到deadline的時候「忽然」想到二叉樹這個等價模型,然後在這個模型下三下五除二就搞定了一篇流芳千古的**,超越了其導師。

霍夫曼使用自底向上的方法構建二叉樹,避免了次優演算法shannon-fano編碼的最大弊端──自頂向下構建樹。2023年,霍夫曼在麻省理工攻讀博士時發表了《一種構建極小多餘編碼的方法》(a method for the construction of minimum-redundancy codes)一文,它一般就叫霍夫曼演算法。

二:分析

霍夫曼編碼,就是一種根據概率構建無損編碼方式。簡單的說,就是把被編碼的物件按照出現概率高低排序,使出現概率高的盡量占用bit少一些,這樣使整體編碼結果較小。wiki上有這麼個例子:

在英文中,e的出現

機率最高,而z的出現概率則最低。當利用霍夫曼編碼對一篇英文進行壓縮時,e極有可能用乙個

位元來表示,而z則可能花去25個

位元(不是26)。用普通的表示方法時,每個英文本母均占用乙個位元組(

byte

),即8個

位元。二者相比,e使用了一般編碼的1/8的長度,z則使用了3倍多。倘若我們能實現對於英文中各個字母出現概率的較準確的估算,就可以大幅度提高無失真壓縮的比例。

為了方便講述,我們說編碼前的是字母流,編碼後的是位元流。然後某字母對應的幾個位元就是它的編碼,學名叫字首碼。這個編碼需要滿足兩個條件:

1. 出現概率大的字母編碼短,概率小的字母編碼長。

2. 編碼後的位元流可以唯一還原成字母流。

比如按照上面的表:0,101,100,111,1101,1100是a,b,c,d,e,f的字首碼,那麼位元流001011101就可以毫無歧義的還原成0.0.101.1101,就是aabe。

怎麼滿足這兩個條件呢?霍夫曼設計了一種方式:二叉樹,因為二叉樹的兩個分叉可以代表0和1,而且樹又是無環的,不會產生歧義。

用樹來表示的話,霍夫曼編碼的cost公式可以這麼表達:cost=σ freq(i) * depth(i),i是所有的葉子節點。

但是如果我們假設所有的父節點的頻率都是兩個子節點的和的話,那麼,cost公式也可以表達為:除了根節點外的所有節點的頻率和。

這樣,假設所有字母的概率值組成乙個集合q,其中fi,fj分別是兩個最小的概率,那麼cost(q)=fi+fj+cost(q'),q'就是q去掉fi和fj並加入概率為(fi+fj)的新節點後組成的新集合。

上圖中,紅框中的節點組成的集合就是q』。

三:**

huffman(c)

n=|c|

q=cfor i=1 to n-1

allocate a new tree node z

z.left=x=extract-min(q)

z.right=y=extract-min(q)

z.freq=x.freq+y.freq

insert(q,z)

return extract-min(q)

其中的extract-min(q)就是從佇列q中取最小數,可以用最小堆。

通過每次都取最小的,最終得到了乙個可用的解,這就是貪心演算法。

假如q是由二叉堆實現的,那麼,建堆使用的時間是o(n),每次調整堆使用的時間是o(lgn),共調整了n-1次。

總之時間複雜為o(nlgn)。

霍夫曼編碼

給定乙個文字中出現的一組字元c,每個字元有其出現頻率freq,想構造字元的最優二進位制表示,即用來編碼整個文字的二進位制位最少 定長編碼 每個字元用相同長度的二進位制位數進行編碼,則每個字元的長度n必須滿足,2 n c 變長編碼 思想是賦予高頻字元短碼字,賦予低頻字元長碼字 編碼過程相對簡單,將表示...

霍夫曼編碼

霍夫曼編碼,或者也可以說哈夫曼編碼。它是一種編碼方式,是可變長編碼 vlc 的一種。準確來說,它是一種方法,什麼方法呢?這種方法,它完全依據字元出現的概率來構造異字頭的平均長度最短的碼字。哈夫曼編碼使用變成編碼表對源字元進行編碼,而這個變長編碼表是通過估算源字元出現的概率得到的。它有個特點,就是出現...

霍夫曼編碼

霍夫曼編碼是可變字長編碼 vlc 的一種。huffman於1952年提出一種編碼方法,該方法完全依據字元出現概率來構造異字頭的平均長度最短的碼字,有時稱之為最佳編碼,一般就稱huffman編碼。霍夫曼編碼的具體方法 先按出現的概率大小排隊,把兩個最小的概率相加,作為新的概率 和剩餘的概率重新排隊,再...