【算法漫画】什么是红黑树?
文章來源于程序員小灰,作者小灰
最近,小灰把這個(gè)知識(shí)點(diǎn)重新做了總結(jié),分成上下兩篇,希望大家把紅黑樹這個(gè)重要的數(shù)據(jù)結(jié)構(gòu)徹底吃透。
—————? 第二天? —————
————————————
二叉查找樹(BST)具備什么特性呢?
1.左子樹上所有結(jié)點(diǎn)的值均小于或等于它的根結(jié)點(diǎn)的值。
2.右子樹上所有結(jié)點(diǎn)的值均大于或等于它的根結(jié)點(diǎn)的值。
3.左、右子樹也分別為二叉排序樹。
下圖中這棵樹,就是一顆典型的二叉查找樹:
1.查看根結(jié)點(diǎn)9:
2.根據(jù)二叉查找樹左子樹小、右子樹大的特性,10 > 9,因此值為10的結(jié)點(diǎn)只可能在根結(jié)點(diǎn)的右子樹當(dāng)中,我們查看右孩子結(jié)點(diǎn)13:
3.由于10 < 13,因此查看左孩子11:
4.由于10 < 11,因此查看左孩子10,發(fā)現(xiàn)10正是要查找的結(jié)點(diǎn):
假設(shè)初始的二叉查找樹只有三個(gè)結(jié)點(diǎn),根結(jié)點(diǎn)值為9,左孩子值為8,右孩子值為12:
接下來我們依次插入如下五個(gè)結(jié)點(diǎn):7,6,5,4,3。依照二叉查找樹的特性,結(jié)果會(huì)變成什么樣呢?
1.結(jié)點(diǎn)是紅色或黑色。
2.根結(jié)點(diǎn)是黑色。
3.每個(gè)葉子結(jié)點(diǎn)都是黑色的空結(jié)點(diǎn)(NIL結(jié)點(diǎn))。
4 每個(gè)紅色結(jié)點(diǎn)的兩個(gè)子結(jié)點(diǎn)都是黑色。(從每個(gè)葉子到根的所有路徑上不能有兩個(gè)連續(xù)的紅色結(jié)點(diǎn))
5.從任一結(jié)點(diǎn)到其每個(gè)葉子的所有路徑都包含相同數(shù)目的黑色結(jié)點(diǎn)。
下圖中這棵樹,就是一顆典型的紅黑樹:
什么情況下會(huì)破壞紅黑樹的規(guī)則,什么情況下不會(huì)破壞規(guī)則呢?我們舉兩個(gè)簡單的例子:
1.向原紅黑樹插入值為14的新結(jié)點(diǎn):
由于父結(jié)點(diǎn)15是黑色結(jié)點(diǎn),因此這種情況并不會(huì)破壞紅黑樹的規(guī)則,無需做任何調(diào)整。
2.向原紅黑樹插入值為21的新結(jié)點(diǎn):
由于父結(jié)點(diǎn)22是紅色結(jié)點(diǎn),因此這種情況打破了紅黑樹的規(guī)則4(每個(gè)紅色結(jié)點(diǎn)的兩個(gè)子結(jié)點(diǎn)都是黑色),必須進(jìn)行調(diào)整,使之重新符合紅黑樹的規(guī)則。
變色:
為了重新符合紅黑樹的規(guī)則,嘗試把紅色結(jié)點(diǎn)變?yōu)楹谏?#xff0c;或者把黑色結(jié)點(diǎn)變?yōu)榧t色。
下圖所表示的是紅黑樹的一部分(子樹),新插入的結(jié)點(diǎn)Y是紅色結(jié)點(diǎn),它的父親結(jié)點(diǎn)X也是紅色的,不符合規(guī)則4,因此我們可以把結(jié)點(diǎn)X從紅色變成黑色:
但是,僅僅把一個(gè)結(jié)點(diǎn)變色,會(huì)導(dǎo)致相關(guān)路徑憑空多出一個(gè)黑色結(jié)點(diǎn),這樣就打破了規(guī)則5。因此,我們需要對(duì)其他結(jié)點(diǎn)做進(jìn)一步的調(diào)整,后文會(huì)詳細(xì)說明。
左旋轉(zhuǎn):
逆時(shí)針旋轉(zhuǎn)紅黑樹的兩個(gè)結(jié)點(diǎn),使得父結(jié)點(diǎn)被自己的右孩子取代,而自己成為自己的左孩子。說起來很怪異,大家看下圖:
圖中,身為右孩子的Y取代了X的位置,而X變成了自己的左孩子。此為左旋轉(zhuǎn)。
右旋轉(zhuǎn):
順時(shí)針旋轉(zhuǎn)紅黑樹的兩個(gè)結(jié)點(diǎn),使得父結(jié)點(diǎn)被自己的左孩子取代,而自己成為自己的右孩子。大家看下圖:
圖中,身為左孩子的Y取代了X的位置,而X變成了自己的右孩子。此為右旋轉(zhuǎn)。
局面1:新結(jié)點(diǎn)(A)位于樹根,沒有父結(jié)點(diǎn)。
(空心三角形代表結(jié)點(diǎn)下面的子樹)
這種局面,直接讓新結(jié)點(diǎn)變色為黑色,規(guī)則2得到滿足。同時(shí),黑色的根結(jié)點(diǎn)使得每條路徑上的黑色結(jié)點(diǎn)數(shù)目都增加了1,所以并沒有打破規(guī)則5。
局面2:新結(jié)點(diǎn)(B)的父結(jié)點(diǎn)是黑色。
這種局面,新插入的紅色結(jié)點(diǎn)B并沒有打破紅黑樹的規(guī)則,所以不需要做任何調(diào)整。
局面3:新結(jié)點(diǎn)(D)的父結(jié)點(diǎn)和叔叔結(jié)點(diǎn)都是紅色。
這種局面,兩個(gè)紅色結(jié)點(diǎn)B和D連續(xù),違反了規(guī)則4。因此我們先讓結(jié)點(diǎn)B變?yōu)楹谏?#xff1a;
這樣一來,結(jié)點(diǎn)B所在路徑憑空多了一個(gè)黑色結(jié)點(diǎn),打破了規(guī)則5。因此我們讓結(jié)點(diǎn)A變?yōu)榧t色:
這時(shí)候,結(jié)點(diǎn)A和C又成為了連續(xù)的紅色結(jié)點(diǎn),我們?cè)僮尳Y(jié)點(diǎn)C變?yōu)楹谏?#xff1a;
經(jīng)過上面的調(diào)整,這一局部重新符合了紅黑樹的規(guī)則。
局面4:新結(jié)點(diǎn)(D)的父結(jié)點(diǎn)是紅色,叔叔結(jié)點(diǎn)是黑色或者沒有叔叔,且新結(jié)點(diǎn)是父結(jié)點(diǎn)的右孩子,父結(jié)點(diǎn)(B)是祖父結(jié)點(diǎn)的左孩子。
我們以結(jié)點(diǎn)B為軸,做一次左旋轉(zhuǎn),使得新結(jié)點(diǎn)D成為父結(jié)點(diǎn),原來的父結(jié)點(diǎn)B成為D的左孩子:
這樣一來,進(jìn)入了局面5。
局面5:新結(jié)點(diǎn)(D)的父結(jié)點(diǎn)是紅色,叔叔結(jié)點(diǎn)是黑色或者沒有叔叔,且新結(jié)點(diǎn)是父結(jié)點(diǎn)的左孩子,父結(jié)點(diǎn)(B)是祖父結(jié)點(diǎn)的左孩子。
我們以結(jié)點(diǎn)A為軸,做一次右旋轉(zhuǎn),使得結(jié)點(diǎn)B成為祖父結(jié)點(diǎn),結(jié)點(diǎn)A成為結(jié)點(diǎn)B的右孩子:
接下來,我們讓結(jié)點(diǎn)B變?yōu)楹谏?#xff0c;結(jié)點(diǎn)A變?yōu)榧t色:
經(jīng)過上面的調(diào)整,這一局部重新符合了紅黑樹的規(guī)則。
以上就是紅黑樹插入操作所涉及的5種局面。
或許有人會(huì)問,如果局面4和局面5當(dāng)中的父結(jié)點(diǎn)B是祖父結(jié)點(diǎn)A的右孩子該怎么辦呢?
很簡單,如果局面4中的父結(jié)點(diǎn)B是右孩子,則成為了局面5的鏡像,原本的右旋操作改為左旋;如果局面5中的父結(jié)點(diǎn)B是右孩子,則成為了局面4的鏡像,原本的左旋操作改為右旋。
給定下面這顆紅黑樹,新插入的結(jié)點(diǎn)是21:
顯然,新結(jié)點(diǎn)21和它的父結(jié)點(diǎn)22是連續(xù)的紅色結(jié)點(diǎn),違背了規(guī)則4,我們應(yīng)該如何調(diào)整呢?
讓我們回顧一下剛才講的5種局面,當(dāng)前的情況符合局面3:
“新結(jié)點(diǎn)的父結(jié)點(diǎn)和叔叔結(jié)點(diǎn)都是紅色?!?/p>
于是我們經(jīng)過三次變色,22變?yōu)楹谏?#xff0c;25變?yōu)榧t色,27變?yōu)楹谏?#xff1a;
經(jīng)過上面的調(diào)整,以結(jié)點(diǎn)25為根的子樹符合了紅黑樹規(guī)則,但結(jié)點(diǎn)25和結(jié)點(diǎn)17成為了連續(xù)的紅色結(jié)點(diǎn),違背規(guī)則4。
于是,我們把結(jié)點(diǎn)25看做一個(gè)新結(jié)點(diǎn),正好符合局面5的鏡像:
“新結(jié)點(diǎn)的父結(jié)點(diǎn)是紅色,叔叔結(jié)點(diǎn)是黑色或者沒有叔叔,且新結(jié)點(diǎn)是父結(jié)點(diǎn)的右孩子,父結(jié)點(diǎn)是祖父結(jié)點(diǎn)的右孩子”
于是我們以根結(jié)點(diǎn)13為軸進(jìn)行左旋轉(zhuǎn),使得結(jié)點(diǎn)17成為了新的根結(jié)點(diǎn):
接下來,讓結(jié)點(diǎn)17變?yōu)楹谏?#xff0c;結(jié)點(diǎn)13變?yōu)榧t色:
如此一來,我們的紅黑樹變得重新符合規(guī)則。
—————END—————
總結(jié)
以上是生活随笔為你收集整理的【算法漫画】什么是红黑树?的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 令程序员心酸的照片
- 下一篇: 【机器学习基础】一文详尽之支持向量机(S