資料結構 AVL樹和紅黑樹的定義

gaopengtttt發表於2016-11-01
這裡只是大概描述了一下AVL的樹的插入,以及紅黑樹的定義,並沒有實現為程式碼,這個在以後的學習中如果遇到會
更加深入的學習,因為我學習資料結構的目的在於如果學習INNODB程式碼的時候遇到不太陌生,但是在INNODB程式碼
中併為找到AVL樹的應用,而紅黑樹的應用僅僅用於資料恢復的時候,所以佔時先了解概念和簡單的操作,如果日後
需要再深入學習,其實資料庫也是各種各樣的資料結構的綜合應用,
比如INNODB:大量的連結串列,夥伴演算法,B+樹,紅黑樹.......
其實學習原始碼很多先決條件至少包含
C/C++精通,資料結構演算法熟悉或者精通,LINUX系統程式設計熟悉或者精通,數字邏輯等。
這些東西對於我來說都要從頭學習,其中任何一門弄到精通都不是易事,而綜合起來
更是難於登天,對我這個門外漢更難,所以很多東西我只能瞭解,學習到在深入研究,
這些東西我已經學習了1年半了這一年半基本沒看資料庫的東西全在看這些,還有基本有一點
熟悉了,但是時間對我來說很少,不能像專業的開發一樣專心的研究這些,因為我只是
一個DBA,還是一個曾經不懂程式碼的ORACLE DBA,如果一直研究這些資料庫的老本都要
忘光,失去了競爭力,準備給自己2年的時間還剩下半年了,2年後繼續研究資料庫如果遇
到不懂的再補補,至少經過這一段時間學習學習到了很多以前不懂的東西,能夠從一個軟體
的角度來看待資料庫,這就是進步。
好吧還是言歸正傳

AVL(self-balancing binary search tree)他就為了解決排序二叉樹(BST)的補足,

也就是BST樹沒有再平衡原理會出現某些極端情況,如下插入1 2 3 4 5 為順序的

資料就會出現如下:

可以看到排序二叉樹搜尋45的時候,搜尋的層次明顯高於平衡二叉樹,

AVL樹透過自我旋轉來完成再平衡原理,其中是根據最小不平衡子樹的

平衡因子來判斷旋轉的方向,所謂不平衡因子就是 左子樹深度-右子樹深度

的差值,平衡二叉樹一個重要的概念就是各個節點的平衡因子只能是-1,0,1

三個值,如果有多個不平衡的子樹那麼需要找到最小的不平衡子樹為旋轉

的基礎,如果解決了最小不平衡子樹的問題其他節點的不平衡性也就解決了

總體的原則

1、如果平衡因子為負數 則進行左旋轉(逆時針)

2、如果平衡因子為正數 這進行右旋轉(順時針)


如下圖加深理解


但是需要分為4種情況

1、簡單左轉如:


節點1的平衡因子為-2 需要逆時針左旋轉


2、簡單右轉如:



 


節點3平衡因子為2需要順時針右轉


3、先左轉再右轉
可以看到節點的5的平衡因子為2,整體需要順時針右旋轉,但是我們發現節點1平衡因為-1,和結點的5的平衡因子符號不同,我們需要對節點進行逆時針左旋然後在對5進行右旋



 



這個時候節點3出現了3個分支,節點4需要進行處理,我們知道實際上43的直接前驅,那麼就行如下變化:



4、先右轉再左轉


可以看到節點2平衡因子為-2,整體需要逆時針左旋轉,但是我們發現節點6的平衡因子為1,和結點2的平衡因為符號不同,我們需要先對節點6進行右旋,然後對節點2進行左旋轉




這個時候節點4出現了3個分支,節點4需要進行處理,我們知道實際上32的直接後繼,那麼就行如下變化:



其他操作先不討論,下面瞭解一下紅黑樹我用INNODB中的註釋給出:
/**********************************************************************//**
Definition of a red-black tree
==============================
A red-black tree is a binary search tree which has the following
red-black properties:
   1. Every node is either red or black.
   2. Every leaf (NULL - in our case tree->nil) is black.
   3. If a node is red, then both its children are black.
   4. Every simple path from a node to a descendant leaf contains the
      same number of black nodes.  
   from (3) above, the implication is that on any path from the root
   to a leaf, red nodes must not be adjacent.
   However, any number of black nodes may appear in a sequence.
 */

/** Red black tree color types */
enum ib_rbt_color_t {
IB_RBT_RED,
IB_RBT_BLACK
};

/** Red black tree node */
struct ib_rbt_node_t {
ib_rbt_color_t color; /* color of this node */
ib_rbt_node_t* left; /* points left child */
ib_rbt_node_t* right; /* points right child */
ib_rbt_node_t* parent; /* points parent node */
char value[1]; /* Data value */
};

實際上中文的限制就是:
1、每個結點要麼是紅的要麼是黑的。  
2、根結點是黑的。  
3、每個葉結點(葉結點即指樹尾端NIL指標或NULL結點)都是黑的。  
4、如果一個結點是紅的,那麼它的兩個兒子都是黑的。  
5、對於任意結點而言,其到葉結點樹尾端NIL指標的每條路徑都包含相同數目的黑結點。 
由於這些限制的出現使得紅黑樹也是一種平衡的二叉樹,在LINUX中也有應用,他的主要
操作也是插入,平衡,刪除,平衡等。
具體可以參考:
http://blog.csdn.net/v_july_v/article/details/6105630
http://blog.csdn.net/eson_15/article/details/51144079
已經MYSQL innodb 原始碼中的紅黑樹實現,我大概看了一下插入和旋轉也不是很難主要是邏輯要清楚。
這裡就不具體解釋了,因為我也是瞭解了一下。
在大概說一下INNODB中的紅黑樹是恢復的時候才用到如下注釋:
ib_rbt_t* flush_rbt; /*!< a red-black tree is used
exclusively during recovery to
speed up insertions in the
flush_list. This tree contains
blocks in order of
oldest_modification LSN and is
kept in sync with the
flush_list.
Each member of the tree MUST
also be on the flush_list.
This tree is relevant only in
recovery and is set to NULL
once the recovery is over.
Protected by flush_list_mutex */

Inserts a modified block into the flush list in the right sorted position.
This function is used by recovery, because there the modifications do not
necessarily come in the order of lsn's. */


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/7728585/viewspace-2127419/,如需轉載,請註明出處,否則將追究法律責任。

相關文章