TreeMap 紅黑樹 原始碼解析

2021-09-26 09:33:29 字數 2530 閱讀 4101

紅黑樹是一種平衡二叉搜尋樹。它可以在o(log n)的時間內完成查詢,插入和刪除。

二叉搜尋樹:左邊的節點都小於父節點,右邊的節點都大於父節點。

平衡二叉樹:任意左右兩個子樹的葉子節點的高度相差不超過1。

關於二叉樹的分類可以看筆者的這篇文章:一句話弄懂常見二叉樹型別

分成這兩個概念來看,紅黑樹就非常好理解了。

二叉搜尋樹的特性非常容易滿足,每次在新增新節點的時候如果小於當前節點,就放到左邊,如果大於當前節點就放到右邊。

紅黑樹為了滿足平衡二叉樹的特性,主要是通過「左旋」和「右旋」兩個操作。

那麼在什麼場景下用「左旋」,什麼場景下用「右旋」呢?這就需要判斷當前節點是「紅」還是「黑」了。也是由於紅黑樹的節點有紅黑之分,所以被稱為「紅黑樹」。

}紅黑樹的查詢操作完全與二叉搜尋樹相同,因此此處就不增長篇幅分析了。

本文主要分析新增與刪除操作的原始碼。

主要邏輯:

直接當做二叉搜尋樹來做插入邏輯。

如果值比當前node小,就走左邊,如果比當前node大就走右邊。

在做完插入之後,通過fixafterinsertion()這個方法來做紅黑樹的結構修正。

fixafterinsertion()中主要有兩個邏輯,一是通過左旋右旋讓紅黑樹到達平衡狀態,二是重新為各節點附上紅黑的顏色。

}主要邏輯:

先刪除在二叉樹中的結點。

刪除該結點後通過fixafterdeletion()來調整紅黑樹的結構。

fixafterdeletion()中主要有兩個邏輯,一是通過左旋右旋讓紅黑樹到達平衡狀態,二是重新為各節點附上紅黑的顏色。

刪除二叉樹中的結點有三種情況:

如果該結點是葉子結點,那麼直接把該結點從父結點刪除。

如果該結點只有左孩子,那麼讓他 的左孩子來替代它原來的位置。

如果該結點只有右孩子,那麼讓他 的右孩子來替代它原來的位置。

如果該結點左右都有孩子,那麼該結點會選擇右子樹中最小的值來替換自己的值,然後把右子樹中最小的值刪除。

public v remove(object key)
private void deleteentry(treemapentryp)  // p has 2 children

// start fixup at replacement node, if it exists.

treemapentryreplacement = (p.left != null ? p.left : p.right);

if (replacement != null) else if (p.parent == null) else }}

static treemapentrysuccessor(treemapentryt)  else 

return p;}}

Set原始碼解析(紅黑樹)

之前粗略看了一下list和map,今咱來聊一下set。主要看以下幾個 1 hashset 2 collections.synchronizedset 3 linkedhashset 4 copyonwritearrayset 5 treeset 一 hashset hashset是日常搬磚中最常用的...

底層實現紅黑樹 Set原始碼解析(紅黑樹)

之前粗略看了一下list和map,今咱來聊一下set。主要看以下幾個 1 hashset 2 collections.synchronizedset 3 linkedhashset 4 copyonwritearrayset 5 treeset 一 hashset hashset是日常搬磚中最常用的...

紅黑樹原始碼及錯誤解析

學校 大學 版本 紅黑樹初始版本 include stdio.h include malloc.h define min 99999999 不要加等號 define max 99999999 struct node long key char color struct node p struct n...