淺析樹結構(三)紅黑樹

淺析樹結構之紅黑樹

首先先來了解一下紅黑樹的五個性質

  1. 每個結點非紅即黑。
  2. 根結點是黑的。
  3. 每個葉結點(這裏葉節點指的是NULL結點)都是黑的。
  4. 如果一個結點是紅的,那麼它的兩個兒子都是黑的。
  5. 對於任意結點而言,其到樹末端即NULL節點的每條路徑都包含相同數目的黑結點。

等等等,一臉懵逼吧?? 那還是先來了解一下2-3樹吧

2-3查找樹

2-3樹是一種樹型數據結構,內部節點(存在子節點的節點)分爲兩種:
(1)2-節點, 有1個數據元素和2個孩子
(2)3-節點, 有2個數據元素和3個孩子

先來看一棵普通的2-3 查找樹到底長什麼樣?

由上圖可以知道, 對於2-3樹中任意一個節點,左右子樹的高度均相同,可見2-3樹是一棵絕對平衡的樹,所有空鏈接到根節點的距離都是相同的.

在一棵大小爲N的2-3樹中,查找和插入操作訪問的結點必然不超過lgN個

2-3樹的插入操作

2-3樹(並不是二叉查找樹)的插入操作與BST(二叉查找樹)的插入操作有很大的區別, BST的插入操作是先進行一次未命中的查找,然後再將節點插入到對應的空鏈接上.如果2-3樹也按照BST這樣進行插入,就破壞了絕對平衡.它採用的方式是將新節點插入到已經存在的葉子節點中.

根據葉子節點的類型不同,插入的處理方式也有所變化:

  • 向2-節點中插入新鍵,直接將新節點合併到原來的節點上組成一個3-節點
  • 向一個父節點爲2-節點的3-節點中插入新鍵(圖中插入4), 這時會產生一個臨時的4-節點, 需要將這個臨時的4-節點分裂爲3個2-節點,並將中間的2-節點上移與其父節點合併成一個3-節點.
  • 向一個父節點爲3-節點的3-節點中插入新鍵,這時會產生一個臨時的4-節點, 需要將這個臨時的4-節點分裂爲3個2-節點,並將中間的2-節點上移與其父節點合併成一個臨時的4-節點, 繼續分裂上移,直到不再存在臨時的4-節點.

爲何不直接使用2-3樹

需要維護兩種不同類型的節點(2-節點,3-節點),兩種類型的節點在轉換,比較等很多情況都相當麻煩,實現代碼所產生的額外開銷可能會導致算法比標準的二叉查找樹速度更慢. 因此我們不使用直接的2-3樹,而是使用更加優秀的紅黑樹 !

紅黑樹與2-3樹的等價性

紅黑樹是 2-3 查找樹,但它不需要分別定義 2- 節點和 3- 節點,而是在普通的二叉查找樹之上,爲節點添加顏色。指向一個節點的鏈接顏色如果爲紅色,那麼這個節點和上層節點表示的是一個 3- 節點,而黑色則是普通鏈接(2-節點)

下圖左邊的2-3樹與右邊的紅黑樹是完全等價的.

2-節點等價於帶有黑色鏈接的節點

3-節點等價於帶有紅色鏈接的節點與上層節點的結合體

紅黑樹的實現—點擊鏈接

BST樹, AVL樹與紅黑樹性能總結:

對於完全隨機的數據, 普通的二分搜索樹很好用!
缺點: 極端情況退化爲鏈表(或者高度不平衡)

對於查詢較多的使用情況,AVL樹很好用!
缺點: AVL樹每次插入刪除會進行大量的平衡度計算,頻繁的插入刪除使AVL樹性能變差

紅黑樹犧牲了平衡性(2logN的高度),但是其統計性能更優秀(綜合增刪改查所有的操作)

基於紅黑樹實現的TreeMap和TreeSet

對TreeMap實現感興趣請點擊這個鏈接------Java集合乾貨系列-(四)TreeMap源碼解析
對TreeSet實現感興趣請點擊這個鏈接------TreeSet源碼分析
另外在Java8中HashMap的實現也使用了紅黑樹,具體分析請點擊這個鏈接------紅黑樹在HashMap中的應用

淺析樹結構(一)二叉查找樹(BST樹代碼實現)
淺析樹結構(二)AVL平衡二叉樹(AVL樹原理及代碼實現)
淺析樹結構(三)紅黑樹

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