樹:BST、AVL、紅黑樹、B樹、B+樹

咱們這個專題介紹的動態查找樹主要有: 二叉查找樹(BST),平衡二叉查找樹(AVL),紅黑樹(RBT),B~/B+樹(B-tree)。這四種樹都具有下面幾個優點:算法

(1) 都是動態結構。在刪除,插入操做的時候,都不須要完全重建原始的索引樹。最多就是執行必定量的旋轉,變色操做來有限的改變樹的形態。而這些操做所付出的代價都遠遠小於重建一棵樹。這一優點在《查找結構專題(1):靜態查找結構概論 》中講到過。數據庫

(2) 查找的時間複雜度大致維持在O(log(N))數量級上。可能有些結構在最差的狀況下效率將會降低很快,好比BST。這個會在下面的對比中詳細闡述。性能

下面咱們開始歸納性描述這四種樹,並相互比較一下優劣。優化

 

1. 二叉查找樹  (Binary Search Tree)   spa

    很顯然,二叉查找樹的發現徹底是由於靜態查找結構在動態插入,刪除結點所表現出來的無能爲力(須要付出極大的代價)。指針

   BST 的操做代價分析:blog

    (1) 查找代價: 任何一個數據的查找過程都須要從根結點出發,沿某一個路徑朝葉子結點前進。所以查找中數據比較次數與樹的形態密切相關。索引

         當樹中每一個結點左右子樹高度大體相同時,樹高爲logN。則平均查找長度與logN成正比,查找的平均時間複雜度在O(logN)數量級上。內存

         當前後插入的關鍵字有序時,BST退化成單支樹結構。此時樹高n。平均查找長度爲(n+1)/2,查找的平均時間複雜度在O(N)數量級上。字符串

    (2) 插入代價: 新結點插入到樹的葉子上,徹底不須要改變樹中原有結點的組織結構。插入一個結點的代價與查找一個不存在的數據的代價徹底相同。

    (3) 刪除代價: 當刪除一個結點P,首先須要定位到這個結點P,這個過程須要一個查找的代價。而後稍微改變一下樹的形態。若是被刪除結點的左、右子樹只有一個存在,則改變形態的代價僅爲O(1)。若是被刪除結點的左、右子樹均存在,只須要將當P的左孩子的右孩子的右孩子的...的右葉子結點與P互換,在改變一些左右子樹便可。所以刪除操做的時間複雜度最大不會超過O(logN)。

    BST效率總結 :  查找最好時間複雜度O(logN),最壞時間複雜度O(N)。

                            插入刪除操做算法簡單,時間複雜度與查找差很少

 

2. 平衡二叉查找樹 ( Balanced Binary Search Tree ) 

    二叉查找樹在最差狀況下居然和順序查找效率至關,這是沒法仍受的。事實也證實,當存儲數據足夠大的時候,樹的結構對某些關鍵字的查找效率影響很大。固然,形成這種狀況的主要緣由就是BST不夠平衡(左右子樹高度差太大)。

    既然如此,那麼咱們就須要經過必定的算法,將不平衡樹改變成平衡樹。所以,AVL樹就誕生了。

    AVL 的操做代價分析:

    (1) 查找代價: AVL是嚴格平衡的BST(平衡因子不超過1)。那麼查找過程與BST同樣,只是AVL不會出現最差狀況的BST(單支樹)。所以查找效率最好,最壞狀況都是O(logN)數量級的。

    (2) 插入代價: AVL必需要保證嚴格平衡(|bf|<=1),那麼每一次插入數據使得AVL中某些結點的平衡因子超過1就必須進行旋轉操做。事實上,AVL的每一次插入結點操做最多隻須要旋轉1次(單旋轉或雙旋轉)。所以,整體上插入操做的代價仍然在O(logN)級別上(插入結點須要首先查找插入的位置)。

    (3) 刪除代價:AVL刪除結點的算法能夠參見BST的刪除結點,可是刪除以後必須檢查從刪除結點開始到根結點路徑上的全部結點的平衡因子。所以刪除的代價稍微要大一些。每一次刪除操做最多須要O(logN)次旋轉。所以,刪除操做的時間複雜度爲O(logN)+O(logN)=O(2logN)

    AVL 效率總結 :  查找的時間複雜度維持在O(logN),不會出現最差狀況

                            AVL樹在執行每一個插入操做時最多須要1次旋轉,其時間複雜度在O(logN)左右。

                            AVL樹在執行刪除時代價稍大,執行每一個刪除操做的時間複雜度須要O(2logN)。

 

3. 紅黑樹 (Red-Black Tree ) 

    二叉平衡樹的嚴格平衡策略以犧牲創建查找結構(插入,刪除操做)的代價,換來了穩定的O(logN) 的查找時間複雜度。可是這樣作是否值得呢?

    能不能找一種折中策略,即不犧牲太大的創建查找結構的代價,也能保證穩定高效的查找效率呢? 答案就是:紅黑樹。

   重要特色:

 1. 每一個紅色結點的兩個子節點必須是黑色的。換句話說:從每一個葉子到根的全部路徑上不能有兩個連續的紅色結點

   2.從任一結點到其每一個葉子的全部路徑都包含相同數目的黑色結點

   因此, 從根到葉子的最長的可能路徑很少於最短的可能路徑的兩倍長。

    RBT 的操做代價分析:

     (1) 查找代價:因爲紅黑樹的性質(最長路徑長度不超過最短路徑長度的2倍),能夠說明紅黑樹雖然不像AVL同樣是嚴格平衡的,但平衡性能仍是要比BST要好。其查找代價基本維持在O(logN)左右,但在最差狀況下(最長路徑是最短路徑的2倍少1),比AVL要略遜色一點。

    (2) 插入代價:RBT插入結點時,須要旋轉操做和變色操做。但因爲只須要保證RBT基本平衡就能夠了。所以插入結點最多隻須要2次旋轉,這一點和AVL的插入操做同樣。雖然變色操做須要O(logN),可是變色操做十分簡單,代價很小。

    (3) 刪除代價:RBT的刪除操做代價要比AVL要好的多,刪除一個結點最多隻須要3次旋轉操做。

    RBT 效率總結 : 查找 效率最好狀況下時間複雜度爲O(logN),但在最壞狀況下比AVL要差一些,但也遠遠好於BST。

                           插入和刪除操做改變樹的平衡性的機率要遠遠小於AVL(RBT不是高度平衡的)。所以須要的旋轉操做的可能性要小,並且一旦須要旋轉,插入一個結點最多隻須要旋轉2次,刪除最多隻須要旋轉3次(小於AVL的刪除操做所須要的旋轉次數)。雖然變色操做的時間複雜度在O(logN),可是實際上,這種操做因爲簡單所須要的代價很小。

 

4. B~樹/B+樹 (B-Tree ) 

     對於在內存中的查找結構而言,紅黑樹的效率已經很是好了(實際上不少實際應用還對RBT進行了優化)。可是若是是數據量很是大的查找呢?將這些數據所有放入內存組織成RBT結構顯然是不實際的。實際上,像OS中的文件目錄存儲,數據庫中的文件索引結構的存儲.... 都不可能在內存中創建查找結構。必須在磁盤中創建好這個結構。那麼在這個背景下,RBT仍是一種好的選擇嗎?

     在磁盤中組織查找結構,從任何一個結點指向其餘結點都有可能讀取一次磁盤數據,再將數據寫入內存進行比較。你們都知道,頻繁的磁盤IO操做,效率是很低下的(機械運動比電子運動要慢不知道多少)。顯而易見,全部的二叉樹的查找結構在磁盤中都是低效的。所以,B樹很好的解決了這一個問題。

    B-Tree的操做代價分析:

    (1) 查找代價: B-Tree做爲一個平衡多路查找樹(m-叉)。B樹的查找分紅兩種:一種是從一個結點查找另外一結點的地址的時候,須要定位磁盤地址(查找地址),查找代價極高。另外一種是將結點中的有序關鍵字序列放入內存,進行優化查找(能夠用折半),相比查找代價極低。而B樹的高度很小,所以在這一背景下,B樹比任何二叉結構查找樹的效率都要高不少。並且B+樹做爲B樹的變種,其查找效率更高。

    (2)插入代價: B-Tree的插入會發生結點的分裂操做。當插入操做引發了s個節點的分裂時,磁盤訪問的次數爲h(讀取搜索路徑上的節點)+2s(回寫兩個分裂出的新節點)+1(回寫新的根節點或插入後沒有致使分裂的節點)。所以,所須要的磁盤訪問次數是h+2s+1,最多可達到3h+1。所以插入的代價是很大的。

    (3)刪除代價:B-Tree的刪除會發生結點合併操做。最壞狀況下磁盤訪問次數是3h=(找到包含被刪除元素須要h次
讀訪問)+(獲取第2至h層的最相鄰兄弟須要h-1次讀訪問)+(在第3至h層的合併須要h-2次寫
訪問)+(對修改過的根節點和第2層的兩個節點進行3次寫訪問)

   B-Tree效率總結: 因爲考慮磁盤儲存結構,B樹的查找、刪除、插入的代價都遠遠要小於任何二叉結構樹(讀寫磁盤次數的下降)。

動態查找樹結構的對比:

(1) 平衡二叉樹和紅黑樹  [AVL  PK  RBT]

      AVL 和RBT 都是二叉查找樹的優化。其性能要遠遠好於二叉查找樹。他們之間都有本身的優點,其應用上也有不一樣。

      結構對比: AVL的結構高度平衡,RBT的結構基本平衡。平衡度AVL > RBT.

      查找對比: AVL 查找時間複雜度最好,最壞狀況都是O(logN)。

                      RBT 查找時間複雜度最好爲O(logN),最壞狀況下比AVL略差。

      插入刪除對比:  1. AVL的插入和刪除結點很容易形成樹結構的不平衡,而RBT的平衡度要求較低。所以在大量數據插入的狀況下,RBT須要經過旋轉變色操做來從新達到平衡的頻度要小於AVL。

                             2. 若是須要平衡處理時,RBT比AVL多一種變色操做,並且變色的時間複雜度在O(logN)數量級上。可是因爲操做簡單,因此在實踐中這種變色仍然是很是快速的。

                             3. 當插入一個結點都引發了樹的不平衡,AVL和RBT都最多須要2次旋轉操做。但刪除一個結點引發不平衡後,AVL最多須要logN 次旋轉操做,而RBT最多隻須要3次。所以二者插入一個結點的代價差很少,但刪除一個結點的代價RBT要低一些。

                             4. AVL和RBT的插入刪除代價主要仍是消耗在查找待操做的結點上。所以時間複雜度基本上都是與O(logN) 成正比的。

        整體評價:大量數據實踐證實,RBT的整體統計性能要好於平衡二叉樹。

(2) B~樹和B+樹    [ B~Tree   PK  B+Tree]

      B+樹是B~樹的一種變體,在磁盤查找結構中,B+樹更適合文件系統的磁盤存儲結構。

      結構對比: B~樹是平衡多路查找樹,全部結點中都包含了待查關鍵字的有效信息(好比文件磁盤指針)。每一個結點如有n個關鍵字,則有n+1個指向其餘結點的指針。

                     B+樹嚴格意義上說已經不是樹,它的葉子結點之間也有指針連接。B+樹的非終結點中並不含有關鍵字的信息,須要查找的關鍵字的所有信息都包含在葉子結點上。非終結點中只做爲葉子結點關鍵字的索引而存在。

      查找對比:1. 在相同數量的待查數據下,B+樹查找過程當中須要調用的磁盤IO操做要少於普通B~樹。因爲B樹所在的磁盤存儲背景下,所以B+樹的查找性能要好於B~樹。

                     2. B+樹的查找效率更加穩定,由於全部葉子結點都處於同一層中,並且查找全部關鍵字都必須走完從根結點到葉子結點的所有歷程。所以同一顆B+樹中,任何關鍵字的查找比較次數都是同樣的。而B樹就不必定了,可能查找到某一個非終結點就結束了。

      插入刪除對比:  B+樹與B~樹在插入刪除操做中的效率是差很少的。

      整體評價:在應用背景下,特別是文件結構存儲中。B+樹的應用要更多,其效率也要比B~樹好。

字符串查找結構

此次專題所講的BST、AVL、BRT、B~Tree等能夠勝任對任何關鍵字數據進行查找。但對字符串的查找(字符串匹配)結構,有專門的結構和算法。

相關文章
相關標籤/搜索