紅黑樹(圖解+秒懂+史上最全)

文章很長,建議收藏起來慢慢讀!瘋狂創客圈總目錄 語雀版 | 總目錄 碼雲版| 總目錄 博客園版 爲您奉上珍貴的學習資源 :


推薦:尼恩Java面試寶典(史上最全 + 面試必備)詳請點擊此鏈接

尼恩Java面試寶典,33個最新pdf,含2000多頁不斷更新、持續迭代 具體詳情,請點擊此鏈接
在這裏插入圖片描述

紅黑樹爲何必須掌握?

來看看,紅黑樹的廣泛的應用

  • JDK 1.8開始,HashMap也引入了紅黑樹:當衝突的鏈表長度超過8時,自動轉爲紅黑樹
  • Java中,TreeMap、TreeSet都使用紅黑樹作爲底層數據結構
  • Linux底層的CFS進程調度算法中,vruntime使用紅黑樹進行存儲。
  • 多路複用技術的Epoll,其核心結構是紅黑樹 + 雙向鏈表。

面試過程中,HashMap 常常是面試的重點, 而且會以連環炮 的方式進行發問,

所以, 紅黑樹基本是 面試必須的 要點如果 答不上來,面試就有 很大程度 就黃了

紅黑樹,又比較複雜,有非常多的場景, 大家記住不容易。

本文,尼恩幫大家做了 徹底,形象的梳理, 幫助大家 輕鬆 記住 紅黑樹

本文的介紹次序

本文,從 BST二叉查找樹, 到AVL 平衡二叉樹, 再到 RBT 紅黑樹,

爲大家 做好 清晰的場景分析, 幫助大家記憶。

BST二叉查找樹

什麼是二叉查找樹呢?

二叉查找樹(BST)具備以下特性:

  1. 左子樹上所有結點的值均小於或等於它的根結點的值。
  2. 右子樹上所有結點的值均大於或等於它的根結點的值。
  3. 左、右子樹也分別爲二叉排序樹。

二叉搜索樹 BST的完美情況

一般人們理解的二叉樹(又叫二叉搜索樹 BST)會出現一個問題,完美的情況下,它是這樣的:

img

二叉搜索樹的查找流程

如何查找值爲7的節點?
1.查看根節點8,因爲7<8,所以再查看它的左子節點6
2.查看左子節點6,因爲7>6,所以再查看它的右子節點7
3.查看右子節點7,因爲7=7,所以就找到啦,

二叉搜索樹的極端情況

二叉查找樹是有缺點的,在不斷插入的時候,有可能出現這樣一種情況:很容易“退化”成鏈表,

如果bst 樹的節點正好從大到小的插入,此時樹的結構也類似於鏈表結構,這時候的查詢或寫入耗時與鏈表相同。

退化成爲了 鏈表的特殊BST

一顆特殊BST,退化成爲了 鏈表,如下圖:

img

它和鏈表一樣,搜索的時候,最壞情況的時間複雜度O(n) 。

那麼我們怎麼避免這種情況呢?

爲了避免這種特殊的情況發生,引入了平衡二叉樹(AVL)和紅黑樹(red-black tree)。

AVL 、rbt 都是通過本身的建樹原則來控制樹的層數和節點位置,

因爲rbtree是由AVL演變而來,所以我們從瞭解AVL開始。

AVL平衡二叉樹

平衡二叉樹也叫AVL(發明者名字簡寫),也屬於二叉搜索樹的一種,與其不同的是AVL通過機制保證其自身的平衡。

AVL樹是最先發明的自平衡二叉查找樹。

在AVL樹中任何節點的兩個子樹的高度最大差別爲1,所以它也被稱爲高度平衡樹。

增加和刪除可能需要通過一次或多次樹旋轉來重新平衡這個樹。

AVL樹的特性

AVL樹本質上還是一棵二叉搜索樹,它有以下特性:

  • 特性1: 對於任何一顆子樹的root根結點而言,它的左子樹任何節點的key一定比root小,而右子樹任何節點的key 一定比root大;

  • 特性2:對於AVL樹而言,其中任何子樹仍然是AVL樹;

  • 特性3:每個節點的左右子節點的高度之差的絕對值最多爲1;

特性1表明,AVL 繼承於 BST , 所以:

1.AVL本身首先是一棵BST 二叉搜索樹。
2.AVL帶有平衡條件:每個結點的左右子樹的高度之差的絕對值(平衡因子)最多爲1。

在插入、刪除樹節點的時候,如果破壞了以上的原則,AVL樹會自動進行調整使得以上三條原則仍然成立。

也就是說,AVL樹,本質上是帶了平衡功能的二叉查找樹(二叉排序樹,二叉搜索樹)。

AVL樹的平衡功能

舉個例子,下左圖爲AVL樹最長的2節點與最短的8節點高度差爲1;

當插入一個新的節點後,根據上面第一條原則,它會出現在2節點的左子樹,但這樣一來就違反了原則3。

img

此時AVL樹會通過節點的旋轉進行進行平衡,

AVL調整的過程稱之爲左旋和右旋,

AVL平衡的調整過程

旋轉之前,首先確定旋轉支點(pivot): 這個旋轉支點就是失去平衡這部分樹,在自平衡之後的根節點,

平衡的調整過程,需要根據pivot它來進行旋轉。

我們在學習AVL樹的旋轉時,不要將失衡問題擴大到整個樹來看,這樣會擾亂你的思路,

我們只關注失衡子樹的根結點 及它的子節點和孫子節點即可。

事實上,AVL樹的旋轉,我們權且叫“AVL旋轉”是有規律可循的,因爲只要聚焦到失衡子樹,然後進行左旋、右旋即可。

很多人在左旋和右旋有時候弄不明白,

其實左旋就是逆時針轉,右旋是順時針轉

AVL子樹失衡的四大場景

導致AVL失衡的場景就是有限的4個:

  • 左左結構失衡(LL型失衡)

  • 右右結構失衡(RR型失衡)

  • 左右結構失衡(LR型失衡)

  • 右左結構失衡(RL型失衡)

刪除元素,也會導致AVL失衡,需要再平衡,但是原理和插入元素是類似的。

這裏聚焦 介紹插入元素的平衡過程, 刪除元素,不做介紹。

場景1: LL型失衡-左左結構失衡(右旋):

場景: 插入的元素在子樹root的左側不平衡元素的左側

此時,以root的左兒爲支點,也就是,左側的不平衡元素爲pivot(支點), 進行右旋

在這裏插入圖片描述

來一個右旋的動畫:

在这里插入图片描述

右旋過程中,如果pivot有右子樹,則作爲 原root的 左子樹, 保障AVL的特性1

記憶要點

尼恩備註記憶要點,LL型失衡怎麼 平衡呢?

旋轉的反向,與失衡的方向相反,

LL 型失衡,與左邊 相反的方向, 是右邊,所以是右旋

場景2 RR型失衡:右右結構失衡(左旋)

場景:插入的元素在子樹root右側的不平衡子樹的右側

此時,以root的右兒爲支點,也就是,右側的不平衡元素 爲 pivot(支點), 進行左旋

img

來一個左旋的動畫:

在这里插入图片描述

左旋過程中,如果pivot有左子樹,則作爲 原root的 右子樹,

保障AVL的特性1,

記憶要點

尼恩備註記憶要點,RR型失衡怎麼 平衡呢?

旋轉的反向,與失衡的方向相反

RR 型失衡,與右邊 相反的方向, 是左邊,所以是左旋

場景3 LR型失衡:左右結構失衡(左旋+右旋):

場景: 插入的元素在左側的不平衡元素的右側

img

記憶要點

尼恩備註記憶要點,LR型失衡怎麼 平衡呢?

旋轉的反向,與失衡的方向相反

LR型失衡,與只相反的方向是 RL,但是先旋轉底部,再旋轉頂部,RL進行次序顛倒,LR

所以, LR型失衡,旋轉的方式,是先左旋, 再右旋

場景4 RL失衡: 右左結構 (右旋+左旋):

場景: 插入的元素在右側的不平衡元素的左側

img

記憶要點

尼恩備註記憶要點,RL型失衡怎麼 平衡呢?

旋轉的反向,與失衡的方向相反

RL型失衡,與只相反的方向是 LR,但是先旋轉底部,再旋轉頂部,所以,LR進行次序顛倒,RL

最終, RL型失衡,旋轉的方式,是先右旋, 再左旋

AVL樹平衡總結

可見無論哪種情況的失衡,都可以通過旋轉來調整。

不難看出,旋轉在圖上像是將pivot(支點)節點向上提(將它提升爲root節點),而後兩邊的節點會物理的分佈在新root節點的兩邊,

接下來按照AVL二叉樹的要求:

左子樹小於root,右子樹大於root進行調整。

從圖LL結構可以看出,當右旋時原來pivot(7)的右子樹(8)會轉變到原root點(9)的左子樹處;

img

從圖右右結構可見,當左旋時,原來pivot(18)的左子樹會分佈到原root點(9)的右子樹。

img

對於左右結構和右左結構無非是經過多次旋轉達到穩定,旋轉的方式並沒有區別,

AVL樹本質上還是一棵二叉搜索樹,它有以下特性:
1.本身首先是一棵二叉搜索樹。
2.帶有平衡條件:每個結點的左右子樹的高度之差的絕對值(平衡因子)最多爲1。

也就是說,AVL樹,本質上是帶了平衡功能的二叉查找樹(二叉排序樹,二叉搜索樹)。

AVL樹的刪除

刪除的判斷標準

  1. 要刪除的節點是什麼類型的節點?;
  2. 刪除後是否會破壞平衡 ;

節點類型

  1. 葉子節點;
  2. 節點只有左子樹或只有右子樹 ;
  3. 既有左右子樹都有。

處理的思路

  1. 當刪除爲葉子節點,則直接刪除,並從父親節點開始往上看,判斷是否失衡;如果沒有失衡,再判斷父親的父節點是否失衡,直到根節點。若失衡則判斷失衡類型(LL、LR、RR、RL),再進行相應的調整。
  2. 刪除的節點只有左子樹或只有右子樹,那麼將節點刪除,以左子樹或右子樹進行代替,並進行相應的平衡判斷,若失衡則調整,一直到根節點 ;
  3. 刪除的節點既有左子樹又有右子樹,找到其前驅或者後驅節點將其替換,再判斷是否失衡,然後根據失衡情況調整,直到根節點。

常見AVL面試題

問:什麼是AVL左旋和右旋?

加入節點後,左旋和右旋 ,維護AVL平衡性

右旋轉

場景: 插入的元素在不平衡元素的左側的左側

x.right = y

y.left = xxx(原x.right)

   對節點y進行向右旋轉操作,返回旋轉後新的根節點x
            y                             x
           / \                          /   \
          x   T4     向右旋轉 (y)        z     y
         / \       - - - - - - - ->    / \   / \
        z   T3                       T1  T2 T3 T4
       / \
     T1   T2

場景:插入的元素在不平衡元素的右側的右側

// 向左旋轉過程

x.left = y;

y.right =(原x.left )

對節點y進行向左旋轉操作,返回旋轉後新的根節點x
        y                             x
      /  \                          /   \
     T1   x      向左旋轉 (y)       y     z
         / \   - - - - - - - ->   / \   / \
       T2  z                     T1 T2 T3 T4
          / \
         T3 T4

AVL樹的問題

既然AVL樹可以保證二叉樹的平衡,這就意味着AVL搜索的時候,它最壞情況的時間複雜度O(logn) ,要低於普通二叉樹BST和鏈表的最壞情況O(n)。

那麼HashMap直接使用AVL樹來替換鏈表就好了,爲什麼選擇用紅黑樹呢?

原因是:

由於AVL樹必須保證左右子樹平衡,Max(最大樹高-最小樹高) <= 1,

所以在插入的時候很容易出現不平衡的情況,一旦這樣,就需要進行旋轉以求達到平衡。

正是由於這種嚴格的平衡條件,導致AVL需要花大量時間在調整上,故AVL樹一般使用場景在於查詢場景, 而不是 增加刪除 頻繁的場景。

紅黑樹(rbt)做了什麼優化呢?

紅黑樹(rbt)繼承了AVL可自平衡的優點,

同時, 紅黑樹(rbt)在查詢速率和平衡調整中尋找平衡,放寬了樹的平衡條件,從而可以用於 增加刪除 頻繁的場景。

在實際應用中,紅黑樹的使用要多得多。

紅黑樹(RBTree)

紅黑樹是一種特化的AVL樹(平衡二叉樹)

紅黑樹是在1972年由Rudolf Bayer發明的,當時被稱爲平衡二叉B樹(symmetric binary B-trees).

在1978年被 Leo J. Guibas 和 Robert Sedgewick 修改爲如今的“紅黑樹”.

什麼是紅黑樹?

紅黑樹也是一種自平衡二叉查找樹,它與AVL樹類似,都在添加和刪除的時候通過旋轉操作保持二叉樹的平衡,以求更高效的查詢性能。

與AVL樹相比,紅黑樹犧牲了部分平衡性,以換取插入/刪除操作時較少的旋轉操作,整體來說性能要優於AVL樹。

雖然RBTree是複雜的, 但它的最壞情況運行時間也是非常良好的,並且在實踐中是高效的:

它可以在O(log n)時間內做查找,插入和刪除,這裏的n 是樹中元素的數目.

紅黑樹的特性

紅黑樹是實際應用中最常用的平衡二叉查找樹,它不嚴格的具有平衡屬性,但平均的使用性能非常良好。

在紅黑樹中,節點被標記爲紅色和黑色兩種顏色。

紅黑樹的原則有以下幾點:

  • 特性1:節點非黑即紅

  • 特性2:根節點一定是黑色

  • 特性3:葉子節點(NIL)一定是黑色

  • 特性4:每個紅色節點的兩個子節點都爲黑色。(從每個葉子到根的所有路徑上不能有兩個連續的紅色節點)

  • 特性5:從任一節點到其每個葉子的所有路徑,都包含相同數目的黑色節點。

紅色屬性 說明,紅色節點的孩子,一定是黑色。 但是,RBTree 黑色節點的孩子,可以是紅色,也可以是黑色,具體如下圖。

葉子屬性 說明, 葉子節點可以是空nil ,AVL的葉子節點不是空的,具體如下圖。

img

基於上面的原則,我們一般在插入紅黑樹節點的時候,會將這個節點設置爲紅色,

原因參照最後一條原則: 紅色破壞原則的可能性最小,如果是黑色, 很可能導致這條支路的黑色節點比其它支路的要多1,破壞了平衡。

記憶要點:

可以按照括號裏邊的分類,記住 紅黑樹的幾個原則:

  • 顏色屬性)性質1:節點非黑即紅

  • 根屬性)性質2:根節點一定是黑色

  • 葉子屬性)性質3:葉子節點(NIL)一定是黑色

  • 紅色屬性)性質4:每個紅色節點的兩個子節點,都爲黑色。(從每個葉子到根的所有路徑上不能有兩個連續的紅色節點)

  • (黑色屬性)性質5:從任一節點到其每個葉子的所有路徑,都包含相同數目的黑色節點。

黑色屬性,可以理解爲平衡特徵, 如果滿足不了平衡特徵,就要進行平衡操作。

空間換時間

RBT有點屬於一種空間換時間類型的優化,

在avl的節點上,增加了 顏色屬性的 數據,相當於 增加了空間的消耗。 通過顏色屬性的增加, 換取,後面平衡操作的次數 減少。

黑色完美平衡

紅黑樹並不是一顆AVL平衡二叉搜索樹,從圖上可以看到,根節點P的左子樹顯然比右子樹高

根據 紅黑樹的特性5,從任一節點到其每個葉子的所有路徑,都包含相同數目的黑色節點, 說明:

rbt 的 左子樹和右子樹的黑節點的層數是相等的

紅黑樹的平衡條件,不是以整體的高度來約束的,而是以黑色 節點的 高度,來約束的。

所以稱紅黑樹這種平衡爲黑色完美平衡

在這裏插入圖片描述

看看黑色完美平衡的效果,

去掉 rbt中的紅色節點,會得到 一個四叉樹, 從根節點到每一個葉子,高度相同,就是rbt的root到葉子的黑色路徑長度。

在這裏插入圖片描述

紅黑樹的恢復平衡過程的三個操作

一旦紅黑樹5個原則有不滿足的情況,我們視爲平衡被打破,如何 恢復平衡?

靠它的三種操作:變色、左旋、右旋

1.變色

節點的顏色由紅變黑或由黑變紅。(這個操作很好了解)

2.左旋

以某個結點作爲支點(pivot),其父節點(子樹的root)旋轉爲自己的左子樹(左旋),pivot的原左子樹變成 原root節點的 右子樹,pivot的原右子樹保持不變。

在这里插入图片描述

img

3.右旋:

以某個結點作爲支點(pivot),其父節點(子樹的root)旋轉爲自己的右子樹(右旋),pivot的原右子樹變成 原root節點的 左子樹,pivot的原左子樹保持不變。

在这里插入图片描述

在這裏插入圖片描述

紅黑樹的左旋、右旋操作,AVL樹的左旋,右旋操作 差不多

紅黑樹插入節點情景分析

紅黑樹的節點結構

先看看紅黑樹的節點結構

以HashMap中的紅黑樹的結構定義爲例子:

  static class Node<K,V> implements Map.Entry<K,V> {
        final int hash;
        final K key;
        volatile V val;
        volatile Node<K,V> next;
        }


/**
 * Nodes for use in TreeBins
 */
static final class TreeNode<K,V> extends Node<K,V> {
    TreeNode<K,V> parent;  // red-black tree links
    TreeNode<K,V> left;
    TreeNode<K,V> right;
    TreeNode<K,V> prev;    // needed to unlink next upon deletion
    boolean red;

    TreeNode(int hash, K key, V val, Node<K,V> next,
             TreeNode<K,V> parent) {
        super(hash, key, val, next);
        this.parent = parent;
    }

默認新插入的節點爲紅色:

因爲父節點爲黑色的概率較大,插入新節點爲紅色,可以避免顏色衝突

場景1:紅黑樹爲空樹

直接把插入結點作爲根節點就可以了

另外:根據紅黑樹性質 2根節點是黑色的。還需要把插入節點設置爲黑色。

場景2:插入節點的Key已經存在

更新當前節點的值,爲插入節點的值。

在這裏插入圖片描述

情景3:插入節點的父節點爲黑色

由於插入的節點是紅色的,當插入節點的父節點是黑色時,不會影響紅黑樹的平衡,

所以: 直接插入無需做自平衡

在這裏插入圖片描述

情景4:插入節點的父節點爲紅色

根據性質2:根節點是黑色。

如果插入節點的父節點爲紅色節點,那麼該父節點不可能爲根節點,所以插入節點總是存在祖父節點(三代關係)。

根據性質4:每個紅色節點的兩個子節點一定是黑色的。不能有兩個紅色節點相連

此時會出現兩種狀態:

  • 父親和叔叔爲紅色

  • 父親爲紅色,叔叔爲黑色

如圖

在這裏插入圖片描述

場景4.1:父親和叔叔爲紅色節點

根據性質4:紅色節點不能相連 ==》祖父節點肯定爲黑色節點:

父親爲紅色,那麼此時該插入子樹的紅黑樹層數的情況是:黑紅紅。

因爲不可能同時存在兩個相連的紅色節點,需要進行 變色, 顯然處理方式是把其改爲:紅黑紅

變色 處理:黑紅紅 ==> 紅黑紅

1.將F和V節點改爲黑色

2.將P改爲紅色

3.將P設置爲當前節點,進行後續處理

在這裏插入圖片描述

可以看到,將P設置爲紅色了,

如果P的父節點是黑色,那麼無需做處理;

但如果P的父節點是紅色,則違反紅黑樹性質了,所以需要將P設置爲當前節點,繼續插入操作, 作自平衡處理,直到整體平衡爲止。

場景4.2:叔叔爲黑色,父親爲紅色,並且插在父親的左節點

分爲兩種情況

  • LL 紅色插入

叔叔爲黑色,或者不存在(NIL)也是黑節點,並且節點的父親節點是祖父節點的左子節點

注意:單純從插入來看,叔叔節點非紅即黑(NIL節點),否則破壞了紅黑樹性質5,此時路徑會比其他路徑多一個黑色節點。

在這裏插入圖片描述

場景4.2.1 LL型失衡

細分場景 1: 新插入節點,爲其父節點的左子節點(LL紅色情況), 插入後 就是LL 型失衡

在這裏插入圖片描述

自平衡處理:

1.變顏色:

將F設置爲黑色,將P設置爲紅色

2.對F節點進行右旋

在這裏插入圖片描述

場景4.2.2 LR型失衡

細分場景 2: 新插入節點,爲其父節點的右子節點(LR紅色情況), 插入後 就是LR 型失衡

在這裏插入圖片描述

自平衡處理:

1.對F進行左旋

2.將F設置爲當前節點,得到LL紅色情況

3.按照LL紅色情況處理(1.變色 2.右旋P節點)
在這裏插入圖片描述

情景4.3:叔叔爲黑節點,父親爲紅色,並且父親節點是祖父節點的右子節點

在這裏插入圖片描述

情景4.3.1:RR型失衡

新插入節點,爲其父節點的右子節點(RR紅色情況)

在這裏插入圖片描述

自平衡處理:

1.變色:

將F設置爲黑色,將P設置爲紅色

2.對P節點進行左旋

在這裏插入圖片描述

情景4.3.2:RL型失衡

新插入節點,爲其父節點的左子節點(RL紅色情況)

在這裏插入圖片描述

自平衡處理:

1.對F進行右旋

2.將F設置爲當前節點,得到RR紅色情況

3.按照RR紅色情況處理(1.變色 2.左旋 P節點)

在這裏插入圖片描述

RBT面試題:

問:有了二叉搜索樹,爲什麼還需要平衡二叉樹?

二叉搜索樹容易退化成一條鏈

這時,查找的時間複雜度從O ( log n)也將退化成O ( N )

引入對左右子樹高度差有限制的平衡二叉樹 AVL,保證查找操作的最壞時間複雜度也爲O ( log n)

問:有了平衡二叉樹,爲什麼還需要紅黑樹?

AVL的左右子樹高度差不能超過1,每次進行插入/刪除操作時,幾乎都需要通過旋轉操作保持平衡

在頻繁進行插入/刪除的場景中,頻繁的旋轉操作使得AVL的性能大打折扣

紅黑樹通過犧牲嚴格的平衡,換取插入/刪除時少量的旋轉操作,

整體性能優於AVL

  • 紅黑樹插入時的不平衡,不超過兩次旋轉就可以解決;刪除時的不平衡,不超過三次旋轉就能解決

  • 紅黑樹的紅黑規則,保證最壞的情況下,也能在O ( log n)時間內完成查找操作。

問:紅黑樹那幾個原則,你還記得麼?

可以按照括號裏邊的分類,記住 紅黑樹的幾個原則:

  • 顏色屬性)節點非黑即紅

  • 根屬性)根節點一定是黑色

  • 葉子屬性)葉子節點(NIL)一定是黑色

  • 紅色屬性)每個紅色節點的兩個子節點,都爲黑色。(從每個葉子到根的所有路徑上不能有兩個連續的紅色節點)

  • (黑色屬性)從任一節點到其每個葉子的所有路徑,都包含相同數目的黑色節點。

問:紅黑樹寫入操作 ,是如何找到它的父節點的?

紅黑樹的節點 TreeNode它就是繼承Node結構,

先看看紅黑樹的節點結構

以HashMap中的紅黑樹的結構定義爲例子:

  static class Node<K,V> implements Map.Entry<K,V> {
        final int hash;
        final K key;
        volatile V val;
        volatile Node<K,V> next;
        }


/**
 * Nodes for use in TreeBins
 */
static final class TreeNode<K,V> extends Node<K,V> {
    TreeNode<K,V> parent;  // red-black tree links
    TreeNode<K,V> left;
    TreeNode<K,V> right;
    TreeNode<K,V> prev;    // needed to unlink next upon deletion
    boolean red;

    TreeNode(int hash, K key, V val, Node<K,V> next,
             TreeNode<K,V> parent) {
        super(hash, key, val, next);
        this.parent = parent;
    }

TreeNode在Node基礎上加了幾個字段,分別指向父節點parent,然後指向左子節點left,還有指向右子節點的right,

然後還有表示顏色red屬性

紅黑樹的插入操作:

首先是找到一個合適的插入點,就是找到插入節點的父節點,

由於紅黑樹 它又滿足BST二叉查找樹的 有序特性,這個找父節點的操作和二叉查找樹是完全一致的。

二叉查找樹,左子節點小於當前節點,右子節點大於當前節點,

然後每一次向下查找一層就可以排除掉一半的數據,查找的效率在log(N)

最終查找到nil節點或者 key一樣的節點。

如果最終查找到 key一樣的節點,進行更新操作。這個TreeNode.key 與當前 put.key 完全一致。這就不需要插入,替換value就可以了,父節點就是當前節點的父節點

如果最終查找到nil節點,進行插入操作。nil節點的父節點,就是當前節點的父節點,把插入的節點替換nil節點。然後進行紅黑樹的 平衡處理。

問:紅黑樹的有那些內部操作

變色

把一個紅色的節點變成黑色,或者把一個黑色的節點變成紅色,就是對這個節點的變色

旋轉

與平衡二叉樹的旋轉操作類似。

紅黑樹與AVL樹區別

1、調整平衡的實現機制不同

紅黑樹根據路徑上黑色節點數目一致,來確定是否失衡,如果失衡,就通過變色和旋轉來恢復

AVL根據樹的平衡因子(所有節點的左右子樹高度差的絕對值不超過1),來確定是否失衡,如果失衡,就通過旋轉來恢復

2、紅黑樹的插入效率更高

紅黑樹是用非嚴格的平衡來換取增刪節點時候旋轉次數的降低,任何不平衡都會在三次旋轉之內解決

紅黑樹並不追求“完全平衡”,它只要求部分地達到平衡要求,降低了對旋轉的要求,從而提高了性能

而AVL是嚴格平衡樹(高度平衡的二叉搜索樹),因此在增加或者刪除節點的時候,根據不同情況,旋轉的次數比紅黑樹要多。

所以紅黑樹的插入效率更高

3、紅黑樹統計性能比AVL樹更高

紅黑樹能夠以O(log n) 的時間複雜度進行查詢、插入、刪除操作。

AVL樹查找、插入和刪除在平均和最壞情況下都是O(log n)

紅黑樹的算法時間複雜度和AVL相同,但統計性能比AVL樹更高

4、適用性:AVL查找效率高

如果你的應用中,查詢的次數遠遠大於插入和刪除,那麼選擇AVL樹,如果查詢和插入刪除次數幾乎差不多,應選擇紅黑樹

即,有時僅爲了排序(建立-遍歷-刪除),不查找或查找次數很少,R-B樹合算一些。

參考文獻:

https://blog.csdn.net/longsq602/article/details/114165028

https://www.jianshu.com/p/d7024b52858c

https://juejin.cn/post/6844903877188272142

https://blog.csdn.net/qq_50227688/article/details/114301326

https://blog.csdn.net/qq116165600/article/details/103361385

https://blog.csdn.net/falling_stars_/article/details/115574847

https://blog.csdn.net/u014454538/article/details/120120216

https://blog.csdn.net/u014454538/article/details/120120216

https://blog.csdn.net/jiang_wang01/article/details/113715033

https://baijiahao.baidu.com/s?id=1680540960651232140&wfr=spider&for=pc

https://www.jianshu.com/p/e136ec79235c

https://www.cnblogs.com/LiaHon/p/11203229.html

http://www.ty2y.com/study/hhszphgc.html

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