定義php
來解釋一下性質和一些定義網站
關於子節點如何定義的3d
爲何要提到234樹呢,由於234樹和紅黑樹是徹底等價的,在程序中實現234樹比較繁瑣,因此使用了紅黑樹來代替指針
來看234樹的添加操做blog
添加若是出現須要分裂的狀況,分裂出的元素首先進行和父級合併,若是父級已是4節點那麼將父級分裂,遞歸操做遞歸
234樹的生長所有都是從葉子節點進行生長的,從葉子節點進行分裂向上延伸get
性質程序
解釋一下性質方法
性質4和性質5說一下im
若是一個紅色節點那麼它的兩個子節點必須爲黑色,包括nil節點,也就是說不能有兩個紅色節點相連
任意一個葉子節點或沒有子節點的節點到根節點通過的黑色節點數量都一致,不懂下面再解釋
葉子節點 : 標記爲NIL,爲虛擬節點,顏色必須爲黑色,234中葉子節點爲沒有子節點的節點,而紅黑樹的葉子節點是虛擬的節點
234樹和紅黑樹對比
3節點的兩種形態若是紅色在左邊就叫作左傾,紅色在右邊就叫作右傾
將234樹進行轉換爲紅黑樹操做
右傾
左傾
如今來看一下幾個沒有子節點的節點下面其實都有兩個NIL節點咱們能夠任意從一個nil節點出發,到6根節點,所通過的黑色節點個數是同樣的,通常狀況下NIL節點是不畫出來的,可是不表明不存在
變色:節點的顏色由黑變紅或者由紅變黑
左旋:以某個節點做爲旋轉點,其右子節點變爲旋轉節點的父節點,右子節點的左子節點變爲旋轉節點的右子節點,左子節點保持不變。
右旋:以某個節點做爲旋轉點,其左子節點變爲旋轉節點的父節點,左子節點的右子節點變爲旋轉節點的左子節點,右子節點保持不變
看圖!
右旋操做
左旋操做
對比234樹進行添加
紅黑樹全部添加的節點默認都爲紅色
1 添加一個根節點
添加第一個默認爲紅色的節點,發現與紅黑樹性質"根節點必須爲黑色"衝突,咱們將5變色爲黑色便可,完成添加操做
2 添加一個節點,與2節點合併
3 添加一個節點,與3節點合併
根據234樹轉紅黑樹的兩種狀態致使添加時可能會出現兩個紅色節點相連的狀況
左傾經過選轉和變色能夠變成右傾的狀態,反之亦然
4 添加一個節點和4節點合併
咱們回到3和4,其中有須要調整的樹
對於3裏面的兩種狀況,看234樹和紅黑樹的對比,4節點的紅黑樹形態是上面黑色節點左右兩邊各一個紅色節點,而如今是三個元素一條線,上面黑色節點,下面兩個紅色,咱們已經知道它的最終形態是什麼樣子,只須要進行調整便可
而對於上面的添加還有一種狀況須要旋轉兩次,解決思路就是變換爲上面的狀況,而後按照上面的步驟完成
而4裏面的狀況,進行變色便可
若是通過變色爺爺節點變色爲紅色,假設不是根節點的話,與上面的其餘節點發生衝突,咱們把變色的爺爺節點當作新增的節點進行操做
若是爺爺節點的父親節點和叔叔節點都爲紅色則繼續按照上面的操做進行調整,若是叔叔節點不是紅色則須要進行其餘調整
例以下圖,若是4的叔叔節點爲紅色,那麼直接根節點變黑(先變紅髮現是根節點而後變黑)便可,若是叔叔節點爲黑色,那麼就須要進行旋轉變色操做
前驅節點和後繼節點
刪除一個節點確定有人要替代被刪除節點的位置,能夠選擇前驅節點或後繼節點
前驅節點 : 小於當前節點的最大節點
後繼節點 : 大於當前節點的最小節點
例如 下面圖的6節點,前驅節點就是5,後繼節點就是9
除非左子樹或右子樹只有一個節點
尋找前驅節點就是尋找左子樹的第一個節點的右兒子,一直往右找直到找到沒有右子節點的節點
尋找後驅節點就是尋找右子樹的第一個節點的左兒子,一直往左找直到找到沒有左子節點的節點
刪除一個節點能夠理解爲刪除它的替換節點
爲何這麼說呢,若是使用代碼實現紅黑樹,一個節點至少有3個指針,左孩子指針,右孩子指針,父親指針,節點中假設就存儲一個值,那麼移除原來的節點替換爲新的節點須要移動:左右孩子指針,父指針,替換的左右孩子指針,左右孩子的父指針.........
而咱們將替換的節點的值賦值給須要刪除的節點,仍是上面那個圖,假如咱們刪除10,使用後繼節點11來替代,咱們只須要將11的值賦值給10,而後刪除11節點便可,也就是說只須要修改兩個指針,11的父指針和12的左孩子指針便可完成
而在234樹中,刪除的永遠都是葉子節點,能夠看上面的圖,前驅節點和後繼節點用於都是在最底層
那麼咱們刪除的狀況從是否有孩子來看就只有兩種
爲何沒有2個孩子的狀況呢?若是刪除一個節點來尋找它的替換節點,那麼要麼是前驅或後繼,而這兩個節點的條件是一直尋找左邊孩子或右邊孩子,若是一個節點有兩個孩子,那麼它確定不是一個前驅或後繼節點
後繼節點同理,若是一個前驅節點或後繼節點有兩個子節點,那麼它必定不是前驅節點或後繼節點
前驅或後繼節點從葉子節點開始的層數不會大於2
那還有個疑問,會不會出現下面這種狀況,10的後繼節點12這都3層了,不是說不會大於2嗎
這種狀況存在嗎?如今都知道紅黑樹是234樹轉換來的,那麼234樹中會出現一個節點只有一個孩子的狀況嗎?
234樹的生長都是從葉子節點進行分裂的,也就是說除了葉子節點,就是說最少的子節點也就是兩個,最多4個,不可能出現上圖的狀況,兩個子節點的節點爲2-節點,2節點除了第一次添加爲根節點或葉子節點之外,任何2-節點都會鏈接兩個子節點,而兩個子節點確定是2,3,4節點其中之一,轉換紅黑樹不可能出現上圖狀況,能夠回去看看234樹轉換紅黑樹對應圖
那麼下面開始進行刪除
先在234樹上進行刪除
能夠直接進行刪除的有4,11,13,其中4和5比較特殊,若是進行的是右傾操做,那麼能夠直接刪除5
在234樹刪除操做中3-節點和4-節點是能夠本身搞定的,例如刪除4或5, 11或12或13,隨便刪除一個都不影響234樹的性質
而在紅黑樹中刪除只能刪除234樹對應的3-節點和4節點中紅色節點,這幾個節點能夠直接刪除,不須要任何額外操做
在紅黑樹中刪除5只須要將4替換掉5,而後進行變色便可,紅黑樹的性質依然保持
刪除
狀況1,本身能搞定,對應234樹當前要的刪除3-節點或4-節點
葉子節點
例如是234樹中的紅色葉子節點或紅黑樹中沒有子節點的紅色節點直接刪除
例如上圖的紅黑樹中4,11,13節點,能夠直接刪除
有一個子節點
使用子節點來替代,若是須要進行變色
例如上圖的紅黑樹中5節點,刪除後4節點替代本身,而後變黑色,而12節點能夠找左兒子或右兒子均可以替換本身
狀況2 本身搞不定,須要兄弟節點和父親節點幫忙
兄弟節點爲3-節點的狀況
例如如今想要刪除5,這時候就須要兄弟節點和父節點幫忙
首先將5刪除,以後須要從兄弟節點拿來一個節點來彌補空缺,可是兄弟節點都比6大,若是直接放入不管是234樹仍是紅黑樹都會違反性質,234 : 3-節點的左子樹元素所有小於key1 ,紅黑樹: 任何一個節點左邊都是小於當前節點
這時咱們把父親節點用來彌補刪除的空缺
以後兄弟節點去彌補父節點的空缺
那麼回到紅黑樹呢?
爲何會出現這種狀況呢?咱們回想一下234樹轉換紅黑樹的圖,在234樹中一個3-節點可能出現左傾或右傾的狀況
上面是6在上面10在下面的狀況,咱們換成相反的狀況來看看
這時5的兄弟節點就和234樹中的同樣了,234樹的3-節點轉換爲紅黑樹的兩種狀況均可以經過左旋變色或右旋變色進行變化
例如上圖,咱們6和8節點進行右旋,就會變成上面第二張圖,而上面的第二張圖6節點和8節點進行左旋又會變成上面的這張圖
有沒有發現一個問題呢,當紅黑樹5節點的兄弟節點爲黑色時也就是說明它的兄弟節點和234樹中5節點的兄弟節點一致
也就是說若是它的兄弟節點爲紅色,須要先進行旋轉變色才能進行刪除,而6和8變色在234樹上等於沒動,由於234樹根本就沒有顏色,只是爲了方便對比紅黑樹添加的顏色
上面的圖還有一種狀況,就是3-節點7和8位置反的,8在上面7在下面,而替代須要兄弟節點中最小的元素來替代,若是出現這種狀況須要先將7和8進行旋轉換色,成爲上面的狀況,而後再進行替換
再來看兄弟節點爲4-節點的狀況
仍是刪除5節點,離它最近的兄弟節點是個4-節點
兄弟節點爲4-節點的刪除
只畫須要修改的地方,先來看234樹
紅黑樹
還有一種方法
而對應紅黑樹就比較簡單了
最後關於變色爲何不是8和9變成黑色,由於紅黑樹必須保證每一個葉子節點到根節點通過黑色節點個數相同,同時保證沒有兩個紅色節點相連,若是是8和9變成黑色,爲了第一條那麼6和7必須變爲紅色,而變成紅色就違反了第二條,上面的刪除第一種操做最後的變色同理,若是7和9爲黑色,那麼從9的葉子節點出發將會比從7的葉子節點多一個黑色節點,違反了紅黑樹的性質
看個動圖加深記憶
這裏使用的是第二種刪除方式,由於能夠少旋轉一次
狀況3,本身解決不了,兄弟節點也幫助不了(兄弟節點也沒有子節點)
若是父親不是紅色節點呢?沒有辦法補償失去的黑色節點?那麼就須要往上面將父節點的兄弟節點變爲紅色,來彌補爺爺節點的黑色平衡,而後將爺爺節點的父節點變黑,可是,若是爺爺節點的父節點也是黑色,那麼就須要遞歸往上進行操做,知道找到父節點不爲黑色的節點
進行上面操做後再根據刪除節點的父節點,把父節點當作要刪除的節點(並不真正刪除),根據上面狀況進行調整
本文僅我的理解,若是有不對的地方歡迎評論指出或私信,謝謝٩(๑>◡<๑)۶