那曲檬骨新材料有限公司

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線(xiàn)課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

紅黑樹(shù)(Red Black Tree)是一種自平衡的二叉搜索樹(shù)

算法與數(shù)據(jù)結(jié)構(gòu) ? 來(lái)源:算法與數(shù)據(jù)結(jié)構(gòu) ? 2020-07-01 15:05 ? 次閱讀

紅黑樹(shù)(Red Black Tree)是一種自平衡的二叉搜索樹(shù)(Self-balancing Binary Search Tree)。以前也叫做平衡二叉 B 樹(shù)(Symmetric Binary B-tree)。

預(yù)備知識(shí)

樹(shù)的知識(shí)框架結(jié)構(gòu)如下圖所示:

平衡二叉搜索樹(shù)

平衡二叉搜索樹(shù)(Balanced Binary Search Tree),英文簡(jiǎn)稱(chēng) BBST。經(jīng)典常見(jiàn)的平衡二叉搜索樹(shù)是 AVL 樹(shù)和紅黑樹(shù)。

①二叉搜索樹(shù)

二叉搜索樹(shù)(Binary Search Tree)是二叉樹(shù)的一種,英文簡(jiǎn)稱(chēng) BST。又稱(chēng)為二叉查找樹(shù)、二叉排序樹(shù)。

它的特點(diǎn)是任何一個(gè)結(jié)點(diǎn)的值都大于其左子樹(shù)的所有結(jié)點(diǎn)的值,任何一個(gè)結(jié)點(diǎn)的值都小于其右子樹(shù)的所有結(jié)點(diǎn)的值。

②平衡

平衡(Balance):就是當(dāng)結(jié)點(diǎn)數(shù)量固定時(shí),左右子樹(shù)的高度越接近,這棵二叉樹(shù)越平衡(高度越低)。而最理想的平衡就是完全二叉樹(shù)/滿(mǎn)二叉樹(shù),高度最小的二叉樹(shù)。

一棵二叉搜索樹(shù)平均時(shí)間復(fù)雜度可以認(rèn)為是樹(shù)的高度 O(h)。像左邊這棵,結(jié)點(diǎn)的左右子樹(shù)的高度接近,屬于一棵平衡二叉搜索樹(shù),O(h) = O(logn);而右邊這棵,高度達(dá)到了最大,已經(jīng)退化成了鏈表,O(h)=O(n)。

③改進(jìn)二叉搜索樹(shù)

當(dāng)二叉樹(shù)退化成鏈表時(shí),性能是很低的,所以我們需要在結(jié)點(diǎn)的插入、刪除操作之后,想辦法讓二叉搜索樹(shù)恢復(fù)平衡(減小樹(shù)的高度)。

但是如果為了追求最理想的平衡,而增加了時(shí)間復(fù)雜度也不是很有必要,因此比較合理的方案就是:用盡量少的調(diào)整次數(shù)達(dá)到適度平衡。

由此引申出 AVL 樹(shù)的概念。

AVL 樹(shù)

AVL 樹(shù)是最早發(fā)明的自平衡二叉搜索樹(shù)之一,它取名自?xún)晌话l(fā)明家的名字:G.M.Adelson-Velsky 和 E.M.Landis。

平衡因子(Balance Factor):某結(jié)點(diǎn)的左右子樹(shù)的高度差。

每個(gè)葉子結(jié)點(diǎn)的平衡因子都是 0??催@棵二叉搜索樹(shù),紅色數(shù)字標(biāo)注了每個(gè)結(jié)點(diǎn)對(duì)應(yīng)的平衡因子。

舉例:8 的左子樹(shù)高度為 2,右子樹(shù)高度為 1,因此它的平衡因子為 1;5 的左子樹(shù)高度為 0,右子樹(shù)高度為 3,因此它的平衡因子為 -3;4 的左子樹(shù)高度為 2,右子樹(shù)高度為 4,因此它的平衡因子為 -2;

再看這棵 AVL 樹(shù)和它每個(gè)結(jié)點(diǎn)對(duì)應(yīng)的平衡因子:

可以看到 AVL 樹(shù)具有以下特點(diǎn):

每個(gè)結(jié)點(diǎn)的平衡因子只可能是 -1、0、1(如果絕對(duì)值超過(guò) 1,則認(rèn)為是失衡)

每個(gè)結(jié)點(diǎn)的左右子樹(shù)高度差不超過(guò) 1

搜索、插入、刪除的時(shí)間復(fù)雜度是 O(logn)

B 樹(shù)

B 樹(shù)(Balanced Tree)是一種平衡的多路搜索樹(shù),多用于文件系統(tǒng)、數(shù)據(jù)庫(kù)的實(shí)現(xiàn)。

這是一個(gè)簡(jiǎn)單的 3 階 B 樹(shù):

特點(diǎn)如下:

1 個(gè)結(jié)點(diǎn)可以存儲(chǔ)超過(guò) 2 個(gè)元素,可以擁有超過(guò) 2 個(gè)子結(jié)點(diǎn)

擁有二叉搜索樹(shù)的一些性質(zhì)

平衡,每個(gè)結(jié)點(diǎn)的所有子樹(shù)高度一致

比較矮

①m 階 B 樹(shù)的性質(zhì)(m ≥ 2)

m 階 B 樹(shù)指的是一個(gè)結(jié)點(diǎn)最多擁有 m 個(gè)子結(jié)點(diǎn)。假設(shè)一個(gè)結(jié)點(diǎn)存儲(chǔ)的元素個(gè)數(shù)為 x,那么如果這個(gè)結(jié)點(diǎn)是:

根結(jié)點(diǎn):1 ≤ x ≤ m - 1

非根結(jié)點(diǎn):┌ m / 2 ┐ - 1 ≤ x ≤ m - 1

如果有子結(jié)點(diǎn),子結(jié)點(diǎn)個(gè)數(shù)為 y = x + 1,那么如果這個(gè)結(jié)點(diǎn)是:

根結(jié)點(diǎn):2 ≤ y ≤ m

非根結(jié)點(diǎn):┌ m / 2 ┐ ≤ y ≤ m

向上取整(Ceiling),指的是取比自己大的最小整數(shù),用數(shù)學(xué)符號(hào) ┌ ┐ 表示;向下取整(Floor),指的是取比自己小的最大整數(shù),用數(shù)學(xué)符號(hào) └ ┘ 表示。 比如 m=3,子結(jié)點(diǎn)個(gè)數(shù) 2≤y≤3,這個(gè) B 樹(shù)可以稱(chēng)為(2,3)樹(shù)、2-3 樹(shù)。 比如 m=4,子結(jié)點(diǎn)個(gè)數(shù) 2≤y≤4,這個(gè) B 樹(shù)可以稱(chēng)為(2,4)樹(shù)、2-3-4 樹(shù)。

比如 m=5,子結(jié)點(diǎn)個(gè)數(shù) 3≤y≤4,這個(gè) B 樹(shù)可以稱(chēng)為(3,5)樹(shù)、3-4-5 樹(shù)。

以此類(lèi)推。

②B 樹(shù) VS 二叉搜索樹(shù)

這是一棵二叉搜索樹(shù),通過(guò)某些父子結(jié)點(diǎn)合并,恰好能與上面的 B 樹(shù)對(duì)應(yīng)。

我們可以得到結(jié)論:

B 樹(shù)和二叉搜索樹(shù),在邏輯上是等價(jià)的

多代結(jié)點(diǎn)合并,可以獲得一個(gè)超級(jí)結(jié)點(diǎn),且 n 代合并的超級(jí)結(jié)點(diǎn),最多擁有 (2^n) 個(gè)子結(jié)點(diǎn) (至少是 (2^n) 階 B 樹(shù))

紅黑樹(shù)定義和性質(zhì)

紅黑樹(shù)是一種含有紅黑結(jié)點(diǎn)并能自平衡的二叉搜索樹(shù)。

為了保證平衡,紅黑樹(shù)必須滿(mǎn)足以下性質(zhì):

每個(gè)結(jié)點(diǎn)是要么是紅色或黑色

根結(jié)點(diǎn)必須是黑色

葉結(jié)點(diǎn)(外部結(jié)點(diǎn)、空結(jié)點(diǎn))是黑色

紅色結(jié)點(diǎn)不能連續(xù)(也就是,紅色結(jié)點(diǎn)的孩子和父親都是黑色)

對(duì)于每個(gè)結(jié)點(diǎn),從該點(diǎn)至nil(樹(shù)尾端,Java 中為null的結(jié)點(diǎn))的任何路徑都包含所相同個(gè)數(shù)的黑色結(jié)點(diǎn)

紅黑樹(shù)與 B 樹(shù)的等價(jià)變換

根據(jù)上面的性質(zhì),可以畫(huà)出這樣一棵紅黑樹(shù)。接下來(lái)對(duì)紅黑樹(shù)做等價(jià)變換,即將所有的紅色結(jié)點(diǎn)上升一層與它的父結(jié)點(diǎn)放在同一行,這就很像一棵 4 階 B 樹(shù),轉(zhuǎn)換效果如下圖所示。

可以得出結(jié)論:

紅黑樹(shù)與 4 階 B 樹(shù)(2-3-4樹(shù))具有等價(jià)性

黑色結(jié)點(diǎn)與紅色子結(jié)點(diǎn)融合在一起,形成 1 個(gè) B 樹(shù)結(jié)點(diǎn)

紅黑樹(shù)的黑色結(jié)點(diǎn)個(gè)數(shù)與 4 階 B 樹(shù)的結(jié)點(diǎn)總個(gè)數(shù)相等

紅黑樹(shù)的基本操作

當(dāng)我們對(duì)一棵平衡二叉搜索樹(shù)進(jìn)行插入、刪除的時(shí)候,很可能會(huì)讓這棵樹(shù)變得失衡(最壞可能導(dǎo)致所有祖先結(jié)點(diǎn)失衡,但是父結(jié)點(diǎn)和非祖先結(jié)點(diǎn)都不可能失衡)。

為了達(dá)到平衡,需要對(duì)樹(shù)進(jìn)行旋轉(zhuǎn)。而紅黑樹(shù)能夠達(dá)到自平衡,靠的也就是左旋、右旋和變色。

旋轉(zhuǎn)操作是局部的。當(dāng)一側(cè)子樹(shù)的結(jié)點(diǎn)少了,向另一側(cè)“借”一些結(jié)點(diǎn);當(dāng)一側(cè)子樹(shù)的結(jié)點(diǎn)多了,則“租”一些結(jié)點(diǎn)給另一側(cè)。

為了更清楚地講解這部分內(nèi)容,先聲明幾個(gè)概念:

N-node:當(dāng)前結(jié)點(diǎn)

P-parent:父結(jié)點(diǎn)

S-sibling:兄弟結(jié)點(diǎn)

U-uncle:叔父結(jié)點(diǎn)(P 的兄弟結(jié)點(diǎn))

G-grand:祖父結(jié)點(diǎn)(P 的父結(jié)點(diǎn))

左旋

左旋指的是以某個(gè)結(jié)點(diǎn)作為支點(diǎn)(旋轉(zhuǎn)結(jié)點(diǎn)),其右子結(jié)點(diǎn)變?yōu)樾D(zhuǎn)結(jié)點(diǎn)的父結(jié)點(diǎn),右子結(jié)點(diǎn)的左子結(jié)點(diǎn)變?yōu)樾D(zhuǎn)結(jié)點(diǎn)的右子結(jié)點(diǎn),左子結(jié)點(diǎn)保持不變。

不考慮結(jié)點(diǎn)顏色,可以看到左旋只影響旋轉(zhuǎn)結(jié)點(diǎn)和其右子樹(shù)的結(jié)構(gòu),把右子樹(shù)的結(jié)點(diǎn)往左子樹(shù)移動(dòng)。

右旋

右旋指的是以某個(gè)結(jié)點(diǎn)作為支點(diǎn)(旋轉(zhuǎn)結(jié)點(diǎn)),其左子結(jié)點(diǎn)變?yōu)樾D(zhuǎn)結(jié)點(diǎn)的父結(jié)點(diǎn),左子結(jié)點(diǎn)的右子結(jié)點(diǎn)變?yōu)樾D(zhuǎn)結(jié)點(diǎn)的左子結(jié)點(diǎn),右子結(jié)點(diǎn)保持不變。

不考慮結(jié)點(diǎn)顏色,可以看到右旋只影響旋轉(zhuǎn)結(jié)點(diǎn)和其左子樹(shù)的結(jié)構(gòu),把左子樹(shù)的結(jié)點(diǎn)往右子樹(shù)移動(dòng)。

變色

變色指的是結(jié)點(diǎn)的顏色由紅變黑或由黑變紅。

變換規(guī)則

將左旋、右旋和變色結(jié)合起來(lái),得到一套變換規(guī)則。

變色:如果當(dāng)前結(jié)點(diǎn)的父結(jié)點(diǎn)和叔父結(jié)點(diǎn)是紅色,那么:

把父結(jié)點(diǎn)和叔父結(jié)點(diǎn)變?yōu)楹谏?/p>

把祖父結(jié)點(diǎn)變?yōu)榧t色

把指針定義到祖父結(jié)點(diǎn)

左旋:當(dāng)前結(jié)點(diǎn)是右子樹(shù),且父結(jié)點(diǎn)是紅色,叔父結(jié)點(diǎn)是黑色,對(duì)它的父結(jié)點(diǎn)左旋。

右旋:當(dāng)前結(jié)點(diǎn)是左子樹(shù),且父結(jié)點(diǎn)是紅色,叔父結(jié)點(diǎn)是黑色,那么:

把父結(jié)點(diǎn)變?yōu)楹谏?/p>

把祖父結(jié)點(diǎn)變?yōu)榧t色

對(duì)祖父結(jié)點(diǎn)右旋

紅黑樹(shù)搜索

由于紅黑樹(shù)本來(lái)就是平衡二叉搜索樹(shù),并且搜索也不會(huì)破壞樹(shù)的平衡,所以搜索算法也與平衡二叉搜索樹(shù)一致:

具體步驟如下:

從根結(jié)點(diǎn)開(kāi)始檢索,把根結(jié)點(diǎn)設(shè)置為當(dāng)前結(jié)點(diǎn)。

若當(dāng)前結(jié)點(diǎn)為空,返回 nil。

若當(dāng)前結(jié)點(diǎn)不為空,比較當(dāng)前結(jié)點(diǎn) key 與搜索 key 的大小。

若當(dāng)前結(jié)點(diǎn) key 等于搜索 key,那么該 key 就是搜索目標(biāo),返回當(dāng)前結(jié)點(diǎn)。

若當(dāng)前結(jié)點(diǎn) key 大于搜索 key,把當(dāng)前結(jié)點(diǎn)的左子結(jié)點(diǎn)設(shè)置為當(dāng)前結(jié)點(diǎn),重復(fù)步驟 2。

若當(dāng)前結(jié)點(diǎn) key 小于搜索 key,把當(dāng)前結(jié)點(diǎn)的右子結(jié)點(diǎn)設(shè)置為當(dāng)前結(jié)點(diǎn),重復(fù)步驟 2。

紅黑樹(shù)插入

紅黑樹(shù)插入操作分為下面兩步:

定位插入的位置

具體步驟如下:

從根結(jié)點(diǎn)開(kāi)始檢索。

若根結(jié)點(diǎn)為空,那么插入結(jié)點(diǎn)設(shè)為根結(jié)點(diǎn),結(jié)束。

若根結(jié)點(diǎn)不為空,那么把根結(jié)點(diǎn)設(shè)為當(dāng)前結(jié)點(diǎn)。

若當(dāng)前結(jié)點(diǎn)為 nil,返回當(dāng)前結(jié)點(diǎn)的父結(jié)點(diǎn),結(jié)束。

若當(dāng)前結(jié)點(diǎn) key 等于搜索 key,那么該 key 所在結(jié)點(diǎn)就是插入結(jié)點(diǎn),更新結(jié)點(diǎn)的值,結(jié)束。

若當(dāng)前結(jié)點(diǎn) key 大于搜索 key,把當(dāng)前結(jié)點(diǎn)的左子結(jié)點(diǎn)設(shè)置為當(dāng)前結(jié)點(diǎn),重復(fù)步驟 4。

若當(dāng)前結(jié)點(diǎn) key 小于搜索 key,把當(dāng)前結(jié)點(diǎn)的右子結(jié)點(diǎn)設(shè)置為當(dāng)前結(jié)點(diǎn),重復(fù)步驟 4。

插入后實(shí)現(xiàn)自平衡

建議新添加的結(jié)點(diǎn)默認(rèn)為紅色,因此這樣能夠讓紅黑樹(shù)的性質(zhì)盡快滿(mǎn)足。不過(guò)如果添加的結(jié)點(diǎn)是根結(jié)點(diǎn),設(shè)為黑色即可。

總結(jié)一下紅黑樹(shù)插入可能出現(xiàn)的所有場(chǎng)景:

①場(chǎng)景 1:紅黑樹(shù)為空樹(shù)

紅黑樹(shù)的性質(zhì) 2:根結(jié)點(diǎn)必須是黑色。

處理:直接把插入結(jié)點(diǎn)設(shè)成黑色并作為根結(jié)點(diǎn)。

②場(chǎng)景 2:插入結(jié)點(diǎn)的 key 已存在

二叉搜索樹(shù)中不能插入相同元素,既然結(jié)點(diǎn)的 key 已經(jīng)存在,紅黑樹(shù)也已平衡,無(wú)需重復(fù)插入。 處理:

將插入結(jié)點(diǎn)設(shè)為將要替換結(jié)點(diǎn)的顏色

更新當(dāng)前結(jié)點(diǎn)的值為插入結(jié)點(diǎn)的值

③場(chǎng)景 3:插入結(jié)點(diǎn)的父結(jié)點(diǎn)為黑色

插入的結(jié)點(diǎn)默認(rèn)是紅色的,當(dāng)它的父結(jié)點(diǎn)是黑色時(shí),并不會(huì)破壞平衡。 處理:直接插入。 ④場(chǎng)景 4:插入結(jié)點(diǎn)的父結(jié)點(diǎn)為紅色

如果插入結(jié)點(diǎn)的父結(jié)點(diǎn)為紅色,那么父結(jié)點(diǎn)不可能為根結(jié)點(diǎn),所以插入結(jié)點(diǎn)總是存在祖父結(jié)點(diǎn)。這點(diǎn)很重要,后續(xù)的旋轉(zhuǎn)操作需要祖父結(jié)點(diǎn)的參與。 場(chǎng)景 4.1:存在叔父結(jié)點(diǎn),且為紅色

由紅黑樹(shù)性質(zhì) 4 可知:紅色結(jié)點(diǎn)不能連續(xù)。那么此時(shí)該插入子樹(shù)的紅黑層數(shù)的情況是:黑-紅-紅。顯然最簡(jiǎn)單的處理方式就是將其改為:紅-黑-紅。

處理:

將父結(jié)點(diǎn)和叔父結(jié)點(diǎn)變?yōu)楹谏?/p>

將祖父結(jié)點(diǎn)變?yōu)榧t色

將祖父結(jié)點(diǎn)設(shè)置為當(dāng)前插入結(jié)點(diǎn)

場(chǎng)景 4.2:叔父結(jié)點(diǎn)不存在或?yàn)楹谏?,插入結(jié)點(diǎn)的父結(jié)點(diǎn)是祖父結(jié)點(diǎn)的左子結(jié)點(diǎn)這種場(chǎng)景下,叔父結(jié)點(diǎn)所在的子樹(shù)的黑色結(jié)點(diǎn)就比父結(jié)點(diǎn)所在子樹(shù)的多,不滿(mǎn)足紅黑樹(shù)的性質(zhì) 5。

場(chǎng)景 4.2.1:插入結(jié)點(diǎn)是左子樹(shù)

處理:

將父結(jié)點(diǎn)變?yōu)楹谏?/p>

將祖父結(jié)點(diǎn)變?yōu)榧t色

將祖父結(jié)點(diǎn)右旋

場(chǎng)景 4.2.2:插入結(jié)點(diǎn)是左子樹(shù)

這種場(chǎng)景顯然可以轉(zhuǎn)換為 4.2.1。

處理:

將父結(jié)點(diǎn)進(jìn)行左旋

將父結(jié)點(diǎn)設(shè)為插入結(jié)點(diǎn),得到場(chǎng)景 4.2.1

進(jìn)行場(chǎng)景 4.2.1 的處理

場(chǎng)景 4.3:叔父結(jié)點(diǎn)不存在或?yàn)楹谏?,插入結(jié)點(diǎn)的父結(jié)點(diǎn)是祖父結(jié)點(diǎn)的右子結(jié)點(diǎn)相當(dāng)于場(chǎng)景 4.2 的方向反轉(zhuǎn),直接看圖。

場(chǎng)景 4.3.1:插入結(jié)點(diǎn)是左子樹(shù)

處理:

將父結(jié)點(diǎn)變?yōu)楹谏?/p>

將祖父結(jié)點(diǎn)變?yōu)榧t色

對(duì)祖父結(jié)點(diǎn)進(jìn)行左旋

場(chǎng)景 4.3.2:插入結(jié)點(diǎn)是右子樹(shù)

處理:

將父結(jié)點(diǎn)進(jìn)行右旋

將父結(jié)點(diǎn)設(shè)置為插入結(jié)點(diǎn),得到場(chǎng)景 4.3.1

進(jìn)行場(chǎng)景 4.3.1 的處理

下面舉個(gè)例子,往一棵紅黑樹(shù)中插入元素,整棵樹(shù)的變換如下圖所示:

紅黑樹(shù)刪除

紅黑樹(shù)刪除操作也分為兩步:

定位刪除的位置

定位刪除位置可以復(fù)用紅黑樹(shù)搜索的操作。

如果不存在目標(biāo)結(jié)點(diǎn),忽略本次操作;如果找到目標(biāo)結(jié)點(diǎn),刪除后進(jìn)行自平衡處理。

刪除后實(shí)現(xiàn)自平衡

二叉搜索樹(shù)刪除的時(shí)候可能出現(xiàn)三種場(chǎng)景:

若刪除結(jié)點(diǎn)無(wú)子結(jié)點(diǎn),直接刪除即可。

若刪除結(jié)點(diǎn)只有一個(gè)子結(jié)點(diǎn),用子結(jié)點(diǎn)替換刪除結(jié)點(diǎn)。

若刪除結(jié)點(diǎn)有兩個(gè)子結(jié)點(diǎn),用**后繼結(jié)點(diǎn)(大于刪除結(jié)點(diǎn)的最小結(jié)點(diǎn))**替換刪除結(jié)點(diǎn)。

具體應(yīng)用,可以借助這張圖理解:

我們可以發(fā)現(xiàn),另外兩種二叉樹(shù)的刪除場(chǎng)景都可以通過(guò)相互轉(zhuǎn)換變?yōu)閳?chǎng)景一。 在場(chǎng)景二情況下:刪除結(jié)點(diǎn)用其唯一的子結(jié)點(diǎn)替換,子結(jié)點(diǎn)替換為刪除結(jié)點(diǎn)后,可以認(rèn)為刪除的是子結(jié)點(diǎn),若子結(jié)點(diǎn)又有兩個(gè)子結(jié)點(diǎn),那么相當(dāng)于轉(zhuǎn)換為場(chǎng)景三,一直自頂向下轉(zhuǎn)換,總是能轉(zhuǎn)換為場(chǎng)景一。

在場(chǎng)景三情況下:刪除結(jié)點(diǎn)用后繼結(jié)點(diǎn),如果后繼結(jié)點(diǎn)有右子結(jié)點(diǎn),那么相當(dāng)于轉(zhuǎn)換為場(chǎng)景二,否則轉(zhuǎn)為場(chǎng)景一。

綜上所述,刪除的結(jié)點(diǎn)可以看作刪除替換結(jié)點(diǎn),且替換結(jié)點(diǎn)最后總是在樹(shù)末。

下面總結(jié)一下紅黑樹(shù)刪除可能出現(xiàn)的所有場(chǎng)景:

為了方面理解,我們先約定一下結(jié)點(diǎn)的叫法:

R:替換結(jié)點(diǎn)

P:替換結(jié)點(diǎn)的父結(jié)點(diǎn)

S:替換結(jié)點(diǎn)的兄弟結(jié)點(diǎn)

SL:兄弟結(jié)點(diǎn)的左子結(jié)點(diǎn)

SR:兄弟結(jié)點(diǎn)的右子結(jié)點(diǎn)

灰色:結(jié)點(diǎn)顏色可能是紅色,也可能是黑色

注意:R 是即將被替換到刪除結(jié)點(diǎn)的位置的替換結(jié)點(diǎn),在刪除前,它還在原來(lái)所在位置參與樹(shù)的子平衡,平衡后再替換到刪除結(jié)點(diǎn)的位置,才算刪除完成。 ①場(chǎng)景 1:替換結(jié)點(diǎn)為紅色 我們把替換結(jié)點(diǎn)換到了刪除結(jié)點(diǎn)的位置時(shí),由于替換結(jié)點(diǎn)為紅色,刪除也了不會(huì)影響紅黑樹(shù)的平衡,只要把替換結(jié)點(diǎn)的顏色變?yōu)閯h除的結(jié)點(diǎn)的顏色即可重新平衡。

處理:替換結(jié)點(diǎn)顏色變?yōu)閯h除結(jié)點(diǎn)的顏色。

②場(chǎng)景 2:替換結(jié)點(diǎn)為黑色

當(dāng)替換結(jié)點(diǎn)是黑色時(shí),就必須進(jìn)行自平衡處理了,我們可以通過(guò)區(qū)分替換結(jié)點(diǎn)是其父結(jié)點(diǎn)的左子結(jié)點(diǎn)還是右子結(jié)點(diǎn),來(lái)做不同的旋轉(zhuǎn),使樹(shù)重新平衡。

場(chǎng)景 2.1:替換結(jié)點(diǎn)是左子樹(shù)場(chǎng)景 2.1.1:替換結(jié)點(diǎn)的兄弟結(jié)點(diǎn)為紅色

若兄弟結(jié)點(diǎn)是紅結(jié)點(diǎn),那么根據(jù)紅黑樹(shù)性質(zhì) 4,兄弟結(jié)點(diǎn)的父結(jié)點(diǎn)和子結(jié)點(diǎn)肯定為黑色,按照下圖方式處理,得到刪除場(chǎng)景 2.1.2.3。

處理:

將兄弟結(jié)點(diǎn)變?yōu)楹谏?/p>

將父結(jié)點(diǎn)變?yōu)榧t色

對(duì)父結(jié)點(diǎn)進(jìn)行左旋,得到場(chǎng)景 2.1.2.3

進(jìn)行場(chǎng)景 2.1.2.3 的處理

場(chǎng)景 2.1.2:替換結(jié)點(diǎn)的兄弟結(jié)點(diǎn)為黑色 當(dāng)兄弟結(jié)點(diǎn)為黑時(shí),其父結(jié)點(diǎn)和子結(jié)點(diǎn)的具體顏色也無(wú)法確定,此時(shí)又得考慮多種子場(chǎng)景。

場(chǎng)景 2.1.2.1:替換結(jié)點(diǎn)的兄弟結(jié)點(diǎn)的右子結(jié)點(diǎn)為紅色,左子結(jié)點(diǎn)任意顏色

即將刪除的左子樹(shù)的一個(gè)黑色結(jié)點(diǎn),顯然左子樹(shù)的黑色結(jié)點(diǎn)少 1 了,然而右子結(jié)點(diǎn)又是紅色,那么我們直接向右子樹(shù)“借”個(gè)紅結(jié)點(diǎn)來(lái)補(bǔ)充黑結(jié)點(diǎn),并進(jìn)行旋轉(zhuǎn)處理。

如圖所示:

處理:

將兄弟結(jié)點(diǎn)的顏色變?yōu)楦附Y(jié)點(diǎn)的顏色

將父結(jié)點(diǎn)變?yōu)楹谏?/p>

將兄弟結(jié)點(diǎn)的右子結(jié)點(diǎn)變?yōu)楹谏?/p>

對(duì)父結(jié)點(diǎn)進(jìn)行左旋

場(chǎng)景 2.1.2.2:替換結(jié)點(diǎn)的兄弟結(jié)點(diǎn)的右子結(jié)點(diǎn)為黑色,左子結(jié)點(diǎn)為紅色 兄弟結(jié)點(diǎn)所在的子樹(shù)有紅結(jié)點(diǎn),又可以向兄弟子樹(shù)“借”個(gè)紅結(jié)點(diǎn)過(guò)來(lái),這就轉(zhuǎn)換回了場(chǎng)景 2.1.2.1。

如圖所示:

處理:

將兄弟結(jié)點(diǎn)變?yōu)榧t色

將兄弟結(jié)點(diǎn)的左子結(jié)點(diǎn)變?yōu)楹谏?/p>

對(duì)兄弟結(jié)點(diǎn)進(jìn)行右旋,得到場(chǎng)景 2.1.2.1

進(jìn)行場(chǎng)景 2.1.2.1 的處理

場(chǎng)景 2.1.2.3:替換結(jié)點(diǎn)的兄弟結(jié)點(diǎn)的子結(jié)點(diǎn)都為黑色

兄弟子樹(shù)沒(méi)有紅結(jié)點(diǎn)可以“借”了,再向父結(jié)點(diǎn)“借”。如果父結(jié)點(diǎn)是黑色,為了讓父結(jié)點(diǎn)在所在的子樹(shù)中保證平衡(替換結(jié)點(diǎn)即將刪除,少了一個(gè)黑色結(jié)點(diǎn),子樹(shù)也需要少一個(gè))先把兄弟結(jié)點(diǎn)變?yōu)榧t色,再讓父結(jié)點(diǎn)成為新的替換結(jié)點(diǎn)。

處理:

如果父結(jié)點(diǎn)為黑色:將兄弟結(jié)點(diǎn)變?yōu)榧t色;將父結(jié)點(diǎn)作為新的替換結(jié)點(diǎn);重新進(jìn)行刪除結(jié)點(diǎn)的場(chǎng)景處理。

如果父結(jié)點(diǎn)為紅色:替換結(jié)點(diǎn)的父結(jié)點(diǎn)和替換結(jié)點(diǎn)的兄弟結(jié)點(diǎn)顏色交換;刪除結(jié)點(diǎn)和替換結(jié)點(diǎn)的值交換后,刪除替換結(jié)點(diǎn)。

場(chǎng)景 2.2:替換結(jié)點(diǎn)是右子樹(shù)

實(shí)際上是場(chǎng)景 2.1 的鏡像操作。

場(chǎng)景 2.2.1:替換結(jié)點(diǎn)的兄弟結(jié)點(diǎn)為紅色

處理:

將兄弟結(jié)點(diǎn)變?yōu)楹谏?/p>

將父結(jié)點(diǎn)變?yōu)榧t色

對(duì)父結(jié)點(diǎn)進(jìn)行右旋,得到場(chǎng)景 2.2.2.3

進(jìn)行場(chǎng)景 2.2.2.3 的處理

場(chǎng)景 2.2.2:替換結(jié)點(diǎn)的兄弟結(jié)點(diǎn)為黑色場(chǎng)景 2.2.2.1:替換結(jié)點(diǎn)的兄弟結(jié)點(diǎn)的左子結(jié)點(diǎn)為紅色,右子結(jié)點(diǎn)任意顏色

處理:

將兄弟結(jié)點(diǎn)的顏色變?yōu)楦附Y(jié)點(diǎn)的顏色

將父結(jié)點(diǎn)變?yōu)楹谏?/p>

將兄弟結(jié)點(diǎn)的左子結(jié)點(diǎn)變?yōu)楹谏?/p>

對(duì)父結(jié)點(diǎn)進(jìn)行右旋

場(chǎng)景 2.2.2.2:替換結(jié)點(diǎn)的兄弟結(jié)點(diǎn)的左子結(jié)點(diǎn)為黑色,右子結(jié)點(diǎn)為紅色

處理:

將兄弟結(jié)點(diǎn)變?yōu)榧t色

將兄弟結(jié)點(diǎn)的右子結(jié)點(diǎn)設(shè)為黑色

對(duì)兄弟結(jié)點(diǎn)進(jìn)行左旋,得到場(chǎng)景 2.2.2.1

進(jìn)行場(chǎng)景 2.2.2.1 的處理

場(chǎng)景 2.2.2.3:替換結(jié)點(diǎn)的兄弟結(jié)點(diǎn)的子結(jié)點(diǎn)都為黑色

處理:

如果父結(jié)點(diǎn)為黑色:將兄弟結(jié)點(diǎn)變?yōu)榧t色;將父結(jié)點(diǎn)作為新的替換結(jié)點(diǎn);重新進(jìn)行刪除結(jié)點(diǎn)的場(chǎng)景處理。

如果父結(jié)點(diǎn)為紅色:替換結(jié)點(diǎn)的父結(jié)點(diǎn)和替換結(jié)點(diǎn)的兄弟結(jié)點(diǎn)顏色交換;刪除結(jié)點(diǎn)和替換結(jié)點(diǎn)的值交換后,刪除替換結(jié)點(diǎn)。

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 二叉樹(shù)
    +關(guān)注

    關(guān)注

    0

    文章

    74

    瀏覽量

    12373
  • null
    +關(guān)注

    關(guān)注

    0

    文章

    19

    瀏覽量

    3998

原文標(biāo)題:面試被問(wèn)“紅黑樹(shù)”,我一臉懵逼......

文章出處:【微信號(hào):TheAlgorithm,微信公眾號(hào):算法與數(shù)據(jù)結(jié)構(gòu)】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    樹(shù)科技在物聯(lián)網(wǎng)方面

    樹(shù)科技在物聯(lián)網(wǎng)領(lǐng)域有多方面的涉及和發(fā)展,以下是些具體信息: 傳感器技術(shù)合作 與傳感器公司合作:宇樹(shù)科技與些傳感器技術(shù)公司有合作,例如奧比中光為宇
    發(fā)表于 02-04 06:48

    使用TFTP加載內(nèi)核設(shè)備樹(shù)

    在嵌入式項(xiàng)目開(kāi)發(fā)中,為了適配新外設(shè)、調(diào)整硬件資源分配或修復(fù)驅(qū)動(dòng)問(wèn)題,需要頻繁修改設(shè)備樹(shù)和內(nèi)核。修改完成后,通常需要重新編譯生成鏡像,并將其燒錄到開(kāi)發(fā)板上進(jìn)行測(cè)試。然而,傳統(tǒng)的燒錄方式不僅需要連接物理接口,還可能因?yàn)殓R像體積較大而耗費(fèi)較長(zhǎng)時(shí)間,這在開(kāi)發(fā)周期緊張的情況下顯得尤為低效。
    的頭像 發(fā)表于 01-17 15:52 ?752次閱讀
    使用TFTP加載內(nèi)核設(shè)備<b class='flag-5'>樹(shù)</b>

    樹(shù)科技CES 2025大放異彩,多款創(chuàng)新產(chǎn)品驚艷亮相

    近日,在萬(wàn)眾矚目的CES 2025展會(huì)上,宇樹(shù)科技攜其最新研發(fā)的系列產(chǎn)品驚艷亮相美國(guó)拉斯維加斯,為全球觀眾帶來(lái)了場(chǎng)科技盛宴。 此次參展,宇樹(shù)科技帶來(lái)了多款備受矚目的機(jī)器人產(chǎn)品。其中
    的頭像 發(fā)表于 01-09 11:32 ?751次閱讀

    嵌入式學(xué)習(xí)-飛凌嵌入式ElfBoard ELF 1板卡-初識(shí)設(shè)備樹(shù)之設(shè)備樹(shù)組成和結(jié)構(gòu)

    項(xiàng)技能。設(shè)備樹(shù)的起源設(shè)備樹(shù)(Device Tree)是一種描述硬件資源的數(shù)據(jù)結(jié)構(gòu),它由uboot傳遞給Linux內(nèi)核,被內(nèi)核解析,內(nèi)核根
    發(fā)表于 01-08 08:32

    飛凌嵌入式ElfBoard ELF 1板卡-初識(shí)設(shè)備樹(shù)之設(shè)備樹(shù)組成和結(jié)構(gòu)

    項(xiàng)技能。設(shè)備樹(shù)的起源設(shè)備樹(shù)(Device Tree)是一種描述硬件資源的數(shù)據(jù)結(jié)構(gòu),它由uboot傳遞給Linux內(nèi)核,被內(nèi)核解析,內(nèi)核根
    發(fā)表于 01-07 09:16

    一千余字解讀stm32時(shí)鐘樹(shù)

    節(jié)概述時(shí)鐘樹(shù)的概念可以類(lèi)比于人體的心臟和血液循環(huán)系統(tǒng)。就像心臟通過(guò)周期性的收縮將血液泵向身體各處樣,MCU的運(yùn)行依賴(lài)于周期性的時(shí)鐘脈沖來(lái)驅(qū)動(dòng)。這些脈沖通常由外部晶體振蕩器提供時(shí)鐘輸入,并最終
    的頭像 發(fā)表于 12-30 21:01 ?1788次閱讀
    一千余字解讀stm32時(shí)鐘<b class='flag-5'>樹(shù)</b>

    飛凌嵌入式ElfBoard ELF 1板卡-內(nèi)核移植之編譯后生成文件說(shuō)明

    進(jìn)制文件,它是由設(shè)備樹(shù)編譯工具DTC (Device tree compiler)編譯dts文件而生成的。關(guān)于設(shè)備樹(shù)的知識(shí),我們?cè)谥笳鹿?jié)有詳細(xì)介紹。 zImage是經(jīng)過(guò)壓縮之后的鏡
    發(fā)表于 12-19 09:11

    飛凌嵌入式ElfBoard ELF 1板卡-內(nèi)核移植之編譯后生成文件說(shuō)明

    Linux內(nèi)核編譯完成之后,會(huì)生成大量的中間文件和目標(biāo)文件,我們這里只介紹比較重要的幾個(gè)文件。我們所關(guān)注的最終需要燒寫(xiě)到開(kāi)發(fā)板的是.dtb設(shè)備樹(shù)鏡像和zImage內(nèi)核鏡像。dtb文件是設(shè)備樹(shù)
    發(fā)表于 12-18 08:52

    請(qǐng)問(wèn)PCM1864的驅(qū)動(dòng)在設(shè)備樹(shù)該如何描述?

    請(qǐng)問(wèn)PCM1864的驅(qū)動(dòng)在設(shè)備樹(shù)該如何描述呢: 1. 我使用的不是TI的LINUX內(nèi)核,是另外款SOC的LINUX內(nèi)核 2. 我在設(shè)備樹(shù)做了以下描述: ps7-i2c@e0004000
    發(fā)表于 10-23 07:30

    什么是默克爾樹(shù)(Merkle Tree)?如何計(jì)算默克爾根?

    01 默克爾樹(shù)的概念 默克爾樹(shù)(Merkle Tree)是一種特殊的二叉樹(shù),它的每個(gè)節(jié)點(diǎn)都存儲(chǔ)了
    的頭像 發(fā)表于 09-30 18:22 ?1090次閱讀
    什么是默克爾<b class='flag-5'>樹(shù)</b>(Merkle <b class='flag-5'>Tree</b>)?如何計(jì)算默克爾根?

    鴻蒙語(yǔ)言基礎(chǔ)類(lèi)庫(kù):ohos.util.HashMap 非線(xiàn)性容器HashMap

    HashMap底層使用數(shù)組+鏈表+樹(shù)的方式實(shí)現(xiàn),查詢(xún)、插入和刪除的效率都很高。HashMap存儲(chǔ)內(nèi)容基于key-value的鍵值對(duì)映射,不能有重復(fù)的key,且個(gè)key只能對(duì)應(yīng)
    的頭像 發(fā)表于 07-10 16:31 ?518次閱讀
    鴻蒙語(yǔ)言基礎(chǔ)類(lèi)庫(kù):ohos.util.HashMap 非線(xiàn)性容器HashMap

    原理圖設(shè)計(jì)里兩顆重要的樹(shù)(國(guó)產(chǎn)EDA)

    原理圖里面兩顆重要的樹(shù),那就是元件樹(shù)和網(wǎng)絡(luò)樹(shù),作為EDA工具中的重要視圖和概念,雖然看似枯燥,但它們扮演著非常重要的角色,它們?yōu)殡娐穲D的層次化結(jié)構(gòu)提供了有力支撐。想象個(gè)大型的電路設(shè)計(jì)
    的頭像 發(fā)表于 05-29 17:47 ?815次閱讀
    原理圖設(shè)計(jì)里兩顆重要的<b class='flag-5'>樹(shù)</b>(國(guó)產(chǎn)EDA)

    圣誕樹(shù)燈電路圖分享

    圣誕裝飾的電路分為兩個(gè)主要部分,即燈光和聲音部分。照明部分由五組 LED 組成,它們以進(jìn)制順序運(yùn)行,每隔幾分鐘就會(huì)重復(fù)次。在這里,根據(jù)我們的興趣,LED 可以是任何顏色。這件裝飾品可以裝飾您的圣誕樹(shù)以及您的家。
    的頭像 發(fā)表于 05-05 10:12 ?1251次閱讀
    圣誕<b class='flag-5'>樹(shù)</b>燈電路圖分享

    OpenHarmony語(yǔ)言基礎(chǔ)類(lèi)庫(kù)【@ohos.util.HashMap (非線(xiàn)性容器HashMap)】

    HashMap底層使用數(shù)組+鏈表+樹(shù)的方式實(shí)現(xiàn),查詢(xún)、插入和刪除的效率都很高。HashMap存儲(chǔ)內(nèi)容基于key-value的鍵值對(duì)映射,不能有重復(fù)的key,且個(gè)key只能對(duì)應(yīng)
    的頭像 發(fā)表于 04-25 22:12 ?899次閱讀
    OpenHarmony語(yǔ)言基礎(chǔ)類(lèi)庫(kù)【@ohos.util.HashMap (非線(xiàn)性容器HashMap)】

    輸電線(xiàn)路通道樹(shù)障巡查及預(yù)警裝置|激光雷達(dá)守護(hù)高壓輸電“生命線(xiàn)”

    輸電線(xiàn)路通道樹(shù)障巡查及預(yù)警裝置|激光雷達(dá)守護(hù)高壓輸電“生命線(xiàn)” 輸電線(xiàn)路作為我國(guó)主要輸入電能的方式之,為現(xiàn)代社會(huì)輸送著源源不斷的電能。然而,在這寧?kù)o的背后,卻隱藏著一種不易察覺(jué)的危險(xiǎn)——那些
    的頭像 發(fā)表于 03-26 15:13 ?803次閱讀
    百家乐官网送彩金平台| 皇冠体育网| 网上百家乐赌钱| 百家乐官网视频交友| 全讯网999| 百家乐怎打能赢| 网上赌百家乐官网被抓应该怎么处理| 凤凰百家乐的玩法技巧和规则| 送彩金百家乐官网平台| 千亿娱乐网| 百家乐平注法到656| 线上百家乐可靠吗| 太阳城百家乐官网的分数| 葡京赌场| 百家乐庄闲比| 百家乐官网的看路技巧| 绍兴市| JJ百家乐的玩法技巧和规则| 百家乐官网九| 百家乐官网网址哪里有| 鸿博娱乐| 百家乐真人游戏棋牌| 百家乐官网平台| 百家乐官网庄家抽水的秘密| 丰台区| 送彩金百家乐的玩法技巧和规则| 百家乐官网网页游戏| 皇室百家乐官网娱乐城| 盈丰国际| 888百家乐的玩法技巧和规则| 百家乐开户送十元| 手机百家乐官网的玩法技巧和规则| 百家乐官网博彩桌出租| 利记线上娱乐| 大发888官方df888gwyxpt| 百家乐国际赌场娱乐网规则| 怎么玩百家乐能赢钱| 百家乐官网冼牌机| 百家乐官网必学技巧| 娱乐城送体验金| 大发888为什么卡|