數據結構中爲了存儲和查找的方便,用各類樹結構來存儲文件,本章就淺談一下各類樹的表示方法、特色及各自的用途,本章設計的樹結構包括:二叉查找樹(二叉排序樹)、平衡二叉樹(AVL樹)、紅黑樹、B-樹、B+樹、字典樹(trie樹)、後綴樹、廣義後綴樹。算法
一、二叉查找樹(二叉排序樹)數據結構
(圖a)搜索引擎
二叉查找樹是一種動態查找表(圖a),具備這些性質:
(1)若它的左子樹不爲空,則左子樹上的全部節點的值都小於它的根節點的值;
(2)若它的右子樹不爲空,則右子樹上全部節點的值都大於它的根節點的值;
(3)其餘的左右子樹也分別爲二叉查找樹;
(4)二叉查找樹是動態查找表,在查找的過程當中可見添加和刪除相應的元素,在這些操做中須要保持二叉查找樹的以上性質。設計
二、平衡二叉樹(AVL樹)指針
(圖b)blog
含有相同節點的二叉查找樹能夠有不一樣的形態,而二叉查找樹的平均查找長度與樹的深度有關,因此須要找出一個查找平均長度最小的一棵,那就是平衡二叉樹(圖b),具備如下性質:
(1)要麼是棵空樹,要麼其根節點左右子樹的深度之差的絕對值不超過1;
(2)其左右子樹也都是平衡二叉樹;
(3)二叉樹節點的平衡因子定義爲該節點的左子樹的深度減去右子樹的深度。則平衡二叉樹的全部節點的平衡因子只多是-1,0,1。排序
三、紅黑樹索引
(圖c)字符串
紅黑樹是一種自平衡二叉樹,在平衡二叉樹的基礎上每一個節點又增長了一個顏色的屬性,節點的顏色只能是紅色或黑色。具備如下性質:
(1)根節點只能是黑色;
(2)紅黑樹中全部的葉子節點後面再接上左右兩個空節點,這樣能夠保持算法的一致性,並且全部的空節點都是黑色;
(3)其餘的節點要麼是紅色,要麼是黑色,紅色節點的父節點和左右孩子節點都是黑色,及黑紅相間;
(4)在任何一棵子樹中,從根節點向下走到空節點的路徑上所通過的黑節點的數目相同,從而保證了是一個平衡二叉樹。效率
四、B-樹
(圖d)
B-樹是一種平衡多路查找樹,它在文件系統中頗有用。一棵m階B-樹(圖d爲4階B-樹),具備下列性質:
(1)樹中每一個節點至多有m棵子樹;
(2)若根節點不是葉子節點,則至少有2棵子樹;
(3)除根節點以外的全部非終端節點至少有棵子樹;
(4)每一個節點中的信息結構爲(A0,K1,A1,K2......Kn,An),其中n表示關鍵字個數,Ki爲關鍵字,Ai爲指針;
(5)全部的葉子節點都出如今同一層次上,且不帶任何信息,也是爲了保持算法的一致性。
五、B+樹
(圖e)
B+數是B-樹的一種變形,它與B-樹的差異在於(圖e爲3階B+樹):
(1)有n棵子樹的節點含有n個關鍵字;
(2)全部的葉子節點包含了所有關鍵字的信息,及指向這些關鍵字記錄的指針,且葉子節點自己按關鍵字大小自小到大順序連接;
(3)全部非終端節點能夠當作是索引部分,節點中僅含有其子樹(根節點)中最大(或最小)關鍵字,全部B+樹更像一個索引順序表;
(4)對B+樹進行查找運算,一是從最小關鍵字起進行順序查找,二是從根節點開始,進行隨機查找。
六、字典樹(trie樹)
(圖f)
字典樹是一種以樹形結構保存大量字符串。以便於字符串的統計和查找,常常被搜索引擎系統用於文本詞頻統計。它的優勢是:利用字符串的公共前綴來節約存儲空間,最大限度地減小無謂的字符串比較,查詢效率比哈希表高。具備如下特色(圖f):
(1)根節點爲空;
(2)除根節點外,每一個節點包含一個字符;
(3)從根節點到某一節點,路徑上通過的字符鏈接起來,爲該節點對應的字符串。
(4)每一個字符串在創建字典樹的過程當中都要加上一個區分的結束符,避免某個短字符串正好是某個長字符串的前綴而淹沒。
七、後綴樹
所謂後綴樹,就是包含一則字符串全部後綴的壓縮了的字典樹。先說說後綴的定義。給定一長度爲n的字符串S=S1S2..Si..Sn,和整數i,1 <= i <= n,子串SiSi+1...Sn都是字符串S的後綴。以字符串S=XMADAMYX爲例,它的長度爲8,因此S[1..8], S[2..8], ... , S[8..8]都算S的後綴,咱們通常還把空字串也算成後綴。這樣,咱們一共有以下後綴。對於後綴S[i..n],咱們說這項後綴起始於i。
全部這些後綴字符串組成一棵字典樹:
仔細觀察上圖,咱們能夠看到很多值得壓縮的地方。好比藍框標註的分支都是獨苗,沒有必要用單獨的節點同邊表示。若是咱們容許任意一條邊裏包含多個字母,就能夠把這種沒有分叉的路徑壓縮到一條邊。另外每條邊已經包含了足夠的後綴信息,咱們就不用再給節點標註字符串信息了。咱們只須要在葉節點上標註上每項後綴的起始位置。因而咱們獲得下圖:
這樣的結構丟失了某些後綴。好比後綴X在上圖中消失了,由於它正好是字符串XMADAMYX的前綴。爲了不這種狀況,咱們也規定每項後綴不能是其它後綴的前綴。要解決這個問題其實挺簡單,在待處理的子串後加一個空字串就好了。例如咱們處理XMADAMYX前,先把XMADAMYX變爲 XMADAMYX$,因而就獲得suffix tree。
這就造成一棵後綴樹了。關於如何創建一棵後綴樹,已有很成熟的算法,能在o(n)時間內解決。
八、廣義後綴樹
廣義後綴樹是好幾個字符串的的全部後綴組成的字典樹,一樣每一個字符串的全部後綴都具備一個相同的結束符,不一樣字符串的結束符不一樣。
傳統的後綴樹只能處理一個單詞的全部後綴。廣義後綴樹存儲任意多個單詞的全部後綴。例如字符串「abab」和「baba」,首先將它們使用特殊結束符連接起來,如表示成「abab$baba#」,而後求鏈接後的新字符的後綴樹,遍歷所得後綴樹,如遇到特殊字符,如「$」,"#"等則去掉以該節點爲跟的子樹,最後所得後綴樹即爲原字符串組的廣義後綴樹。其實質是將兩個字符串的全部後綴,即:abab$,bab$,ab$,b$,baba#,aba#,ba#,a#,組成字典樹,再進行壓縮處理。廣義後綴樹的一個常應用就是判斷兩個字符串的相識度。