huffman樹又叫最優樹,是一類帶權路徑長度最短的樹,有著廣泛的應用。
1、 最優二叉樹
從樹中乙個節點到另乙個結點之間的分支構成這兩個結點之間的路徑,路徑上的分支數目稱做路徑長度。樹的路徑長度是從樹根到每乙個結點的路徑長度之和。結點的帶權路徑長度為從該節點到樹根之間的路徑長度與節點上權的乘積,樹的帶權路徑長度為樹中所有葉子節點的帶權路徑長度之和,記作
假設有n個權值
例如,圖1中3棵二叉樹有4個葉子節點a、b、c、d,分別帶權7、5、2、4,則他們帶權路徑長度分別為
其中(c)樹最小。恰為huffman樹。
圖1 具有不同帶權路徑長度的二叉樹
那麼,如何構造huffman樹呢?步驟如下:
(1) 將給定的n個權值
(2) 選擇兩個最小權值的二叉樹分別作為左右子樹構造一棵新的二叉樹,新樹的根節點權值為左右子樹之和。
(3) 在二叉樹集合中刪除合併的兩棵二叉樹,新增新得到的二叉樹。
(4) 重複步驟(2)(3)直到集合中只含一棵二叉樹為止。
如圖2所示,為huffman樹的構造過程。
圖2 huffman樹的構造過程
2、 huffman編碼
利用二叉樹來設計二進位制的字首編碼(任一字元編碼都不是另乙個字元編碼的字首),假設每種字元在電文中出現的次數為
huffman編碼具體做法:由於huffman樹中沒有度為1的結點,則一棵有n個葉子節點的huffman樹共有2n-1個結點,可以儲存在乙個2n-1的陣列中。由於構成huffman樹後,為求編碼需從葉子節點出發到根,而為解碼需從根出發的葉子節點,則對每個結點而言,既需知道雙親資訊,又需知道孩子結點的資訊。
huffman編碼的c程式:
typedef
struct
hnode,*huffmantree;//動態分配陣列儲存huffman樹
typedef
char* huffmancode;//動態分配陣列儲存huffman編碼表
//huffman編碼
void huffmancoding(huffmantree ht,huffmancode hc,int * w,int n)
int m=2*n-1;
ht=(huffmantree)malloc((m+1)*sizeof(hnode));
for(int i=1;i<=n;i++)
for(;i<=m;i++)
//構建huffman樹
int min1,min2;
for(i=n+1;i<=m;i++)
//從葉子到根逆向求每個字元的huffman編碼
hc=(huffmancode)malloc((n+1)*sizeof(char*));//分配n個字元編碼的頭指標向量
char* cd=(char*)malloc(n*sizeof(char));//分配求編碼的工作空間
cd[n-1]='\0';
for(int i=1;i<=n;i++)//逐個字元求huffman編碼
else
cd[--start]='1';
}hc[i]=(char*)malloc((n-start)*sizeof(char));//為第i個字元編碼分配空間
strcpy(hc[i],cd[start]);
}free(cd);
}
資料結構Huffman樹及編碼
一 實驗目的 構造乙個哈夫曼樹,並根據所構造的哈夫曼樹求其哈夫曼樹的編碼 二 基本思路 將每個英文本母依照出現頻率由小排到大,最小在左,組成乙個序列 每個字母都代表乙個終端節點 葉節點 比較每個字母的出現頻率,將最小的兩個字母頻率相加合成乙個新的節點,將兩個字母從序列中刪除,將生成的節點加入到字母佇...
資料結構學習 樹
樹結構是二叉樹的擴充套件,二叉樹在乙個節點上只有兩個子節點,而樹結構在乙個節點上不只有兩個,可以有n個,n大於等於0,更具有一般意義。二叉樹的概念同樣適用於樹,如完全數,滿樹等,此外還有 有序樹 結點的各子樹從左到右是有次序的,即若交換各子樹相對位置會構成不同的樹。無序樹 結點的各子樹從左到右是無次...
資料結構學習 樹
樹是n個結點的有限集合。n 0時稱為空樹,在任意一棵非空樹中 1 有且僅有乙個特定的稱為根的結點。2 當n 1時,其餘結點可以分為m個互不相交的有限集合,其中每乙個集合本身又是一棵樹。在此,我們主要來學習二叉樹的應用。結點擁有的子樹數稱為結點的度。度為0的結點稱為葉子結點或者終端結點。度不為0的結點...