Huffman樹,紅黑樹,線索二叉樹

數據結構之huffman 樹

帶權、路徑長度最短的樹
路徑:從樹中一個結點到另一個結點之間的分支構成這兩個結點間的~
路徑長度:路徑上的分支數
樹的路徑長度:從樹根到每一個結點的路徑長度之和
在許多應用中,常常將樹中結點賦予一個有某種意義的實數,稱爲該結點的權。
結點的帶權路徑長度:是該結點到樹根之間的路徑長度與結點上權的乘積。
樹的帶權路徑長度:樹中所有葉子結點(k)的帶權路徑長度ωk lk之和, 記做WPL.

下面通過一個實例進行說明:有4個結點,權值分別爲7,5,2,4,構造有4個葉子結點的二叉樹


設有n個權值{w1,w2,……wn},
構造一棵有n個葉子結點的二叉樹,每個葉子權值爲wi,則WPL最小的二叉樹叫Huffman樹
哈夫曼樹中沒有度爲1的結點,稱爲嚴格的二叉樹

2. huffman算法

構造Huffman樹的方法:Huffman算法

1.根據給定的n個權值{w1,w2,……wn},構造n棵只有根結點的二叉樹Tj,令其權值爲wj
2.在森林中選取兩棵根結點權值最小的樹作左右子樹,構造一棵新的二叉樹,置新二叉樹根結點權值爲其左右子樹根結點權值之和
3.在森林中刪除這兩棵樹,同時將新得到的二叉樹加入森林中
4.重複上述兩步,直到只含一棵樹爲止,這棵樹即哈夫曼樹

w={7,5,2,4}

構建步驟如下圖所示:


3. 採用堆來構造Huffman樹

順序表中是n個權,
1。每個權生成一個僅有根的二叉鏈表,將根指針入堆。
2。從堆中刪除2個結點,權和生成雙親結點,根入堆。
重複直2步驟n-1次。返回根指針。

解釋說明:將每個權生成的僅有root的二叉鏈表的根指針全部入堆,這樣堆頂就是最小的權,然後從堆中刪除兩個節點,根據堆的性質,刪除的兩個節點剛好就是最小的兩個權值,從這兩個權值構造一個雙親節點,並將root入堆,然後重複該步驟,每次都選取兩個最小的權去構造新的子樹,並將入堆,這樣重複n-1次之後就構成了Huffman樹。算法中採用了堆這個具有排序結構(優先級)的數據結構,能夠很好的解決生成Huffman樹的問題。

4. huffman樹節點的存儲結構及代碼實現

 

5. Huffman樹的應用:Huffman編碼

數據通信用的二進制編碼

思想:根據字符出現頻率編碼,使電文總長最短編碼:

根據字符出現頻率構造Huffman樹,然後將樹中結點引向其左孩子的分支標 “0”,引向其右孩子的分支標“1”;每個字符的編碼即爲從根到每個葉子的路徑上得到的0、1序列

舉例說明:它們的出現頻率依次爲4、7、5、2、9,試畫出對應的哈夫曼樹(請按左子樹根結點的權小於等於右子樹根結點的權的次序構造),並求出每個字符的哈夫曼編碼


具體的編碼數組結構描述如下:

typedef char datatype;
typedef struct
{
    char bits[n];
    int start;
    datatype data;
}codetype;
codetype code[n];

編碼算法的基本思想:

從葉子tree[i]出發,利用雙親地址找到雙親結點tree[p],再利用tree[p]的lchild和rchild指針域判斷tree[i] 是tree[p]的左孩子還是右孩子,然後決定分配代碼是“0”還是“1”,然後以tree[p]爲出發點繼續向上回溯,直到根結點爲止。

數據結構之紅黑樹

1. 基本概念

紅黑樹是一種自平衡二叉查找樹,是在計算機科學中用到的一種數據結構,典型的用途是實現關聯數組。它是在1972年由Rudolf Bayer發明的,他稱之爲"對稱二叉B樹",它現代的名字是在 Leo J. Guibas 和 Robert Sedgewick 於1978年寫的一篇論文中獲得的。它是複雜的,但它的操作有着良好的最壞情況運行時間,並且在實踐中是高效的: 它可以在O(log n)時間內做查找,插入和刪除,這裏的n 是樹中元素的數目。
紅黑樹是一種很有意思的平衡檢索樹。它的統計性能要好於平衡二叉樹(有些書籍根據作者姓名,Adelson-Velskii和Landis,將其稱爲AVL-樹),因此,紅黑樹在很多地方都有應用。在C++ STL中,很多部分(目前包括set, multiset, map, multimap)應用了紅黑樹的變體(SGI STL中的紅黑樹有一些變化,這些修改提供了更好的性能,以及對set操作的支持)。

2. 紅黑樹的性質

首先紅黑樹是二叉查找樹,紅黑樹確保沒有一條路徑會比其他路徑長出兩倍,因而是接近平衡的,所以是一種近似平衡二叉搜索樹。

那麼必須滿足如下二叉查找樹的性質:

(1).在一棵二叉查找樹上,執行查找、插入、刪除等操作,的時間複雜度爲O(lgn)。
    因爲,一棵由n個結點,隨機構造的二叉查找樹的高度爲lgn,所以順理成章,一般操作的執行時間爲O(lgn)。
    //至於n個結點的二叉樹高度爲lgn的證明,可參考算法導論 第12章 二叉查找樹 第12.4節。
(2).但若是一棵具有n個結點的線性鏈,則此些操作最壞情況運行時間爲O(n)。

而紅黑樹能保證在最壞的情況下,基本動態幾何操作時間均爲O(lgn)

紅黑樹上每個結點內含五個域,color,key,left,right,p。如果相應的指針域沒有,則設爲NIL。
一般的,紅黑樹,滿足以下性質,即只有滿足以下全部性質的樹,我們才稱之爲紅黑樹:
1)每個結點要麼是紅的,要麼是黑的。
2)根結點是黑的。
3)每個葉結點,即空結點(NIL)是黑的。
4)如果一個結點是紅的,那麼它的倆個兒子都是黑的。
5)對每個結點,從該結點到其子孫結點的所有路徑上包含相同數目的黑結點。

如圖所示:


3. 樹的旋轉

在對紅黑樹進行插入和刪除等操作時,對樹做了修改,那麼可能會違背紅黑樹的性質。爲了保持紅黑樹的性質,我們可以通過對樹進行旋轉,即修改樹種某些結點的顏色及指針結構,以達到對紅黑樹進行
插入、刪除結點等操作時,紅黑樹依然能保持它特有的性質(如上文所述的,五點性質)。
 
樹的旋轉,分爲左旋和右旋,以下藉助圖來做形象的解釋和介紹:

(1) 左旋


(2) 右旋



數據結構之線索二叉樹

1 基本概念

使用二叉鏈表無法直接找到每一個節點在某一種遍歷序列中的前驅後繼,而具有n個節點的二叉鏈表必定存在n+1個空鏈域,可以用來存放前驅和後繼的指針,並稱之爲線索(thread),具體的作法:

若節點有左子樹,則其左指針指向左孩子;否則另它指向前驅;

若節點有右子樹,則其右指針指向右孩子;否則另它指向後繼。

爲此,二叉鏈表的節點結構需要增加兩個標誌域,指明左右鏈域中的指針是指向左右孩子還是指向前驅後繼。

帶有線索的二叉鏈表成爲線索鏈表,相應的二叉樹稱之爲線索二叉樹。


2. 線索二叉樹節點定義

如圖所示:


對線索鏈表中結點的約定:在二叉鏈表的結點中增加兩個標誌域
若該結點的左子樹不空,則Lchild域的指針指向其左子樹且左標誌域的值爲“指針 Link”否則,Lchild域的指針指向其“前驅”,且左標誌的值爲“線索 Thread”
若該結點的右子樹不空,則rchild域的指針指向其右子樹,且右標誌域的值爲 “指針 Link”;否則,rchild域的指針指向其“後繼”,且右標誌的值爲“線索 Thread”。
如此定義的二叉樹的存儲結構稱作“線索鏈表”。



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章