你要刪除的節點x可分爲三類:有兩個子節點的,只有一個子節點的,以及沒有子節點的。因爲刪除有兩個子節點的狀況能夠轉化爲後兩種狀況(找到待刪除節點的後繼節點y,將該節點的值放在x處,x處的顏色不變,注意這時候既沒有破壞二叉搜索樹的性質,也沒有破壞紅黑樹關於節點顏色的性質,咱們只要接着刪除節點y便可,而節點y最多隻會有一個子節點。)
只有一個子節點時,用該子節點代替刪除節點的位置(保留子節點本身的顏色和值),只有一個子節點時,直接刪除便可。若是刪除的節點是紅色,那麼就萬事大吉了, 由於刪除一個紅色節點不會破壞紅黑樹關於節點顏色的性質,而上述全部的刪除操做也不會破壞二叉搜索樹的性質。刪除該紅色節點後仍是一個合法的紅黑樹。
若是刪除的節點是一個黑色節點,那麼就須要進行接下來的處理:
因爲刪除操做,某些路徑上會少一個黑色節點。在此咱們假設,刪除的節點爲x,刪除x後代替x位置的是節點y(當x沒有子節點時,y就是是個null,然而算法導論裏將全部unll節點稱之爲葉節點,並具備黑色顏色,這樣處理確實方便了不少,這裏和普通的樹的定義不一樣,注意)。
咱們假設y節點除了自己的顏色外,另外又攜帶有一個黑色顏色,這樣咱們就將某些路徑上少一個黑色節點的矛盾等價爲某一節點具備兩個顏色的矛盾。那麼咱們如何處理這個擁有兩個顏色的節點y呢?
<1.若是y的顏色爲紅+黑,那麼直接去掉紅色顏色,不破壞紅黑樹性質。
<2.若是y是根節點(那麼顏色必定是黑+黑),那麼直接去掉一個黑色,這時全部路徑上的黑色節點都少了1,但都相等,也不破壞紅黑樹性質。
根據這兩條性質,咱們須要處理的矛盾節點就是黑+黑色的(只要一碰到紅+黑就用狀況1處理,完成刪除)
接下來開始分類討論,這裏咱們不妨假設節點y是其父節點的左節點(相反狀況所有對稱處理)。
狀況1,y的兄弟節點b是紅色,那麼y的父節點和b的兩個孩子都是黑色,這時對父節點作左旋操做並交換父親節點和b的顏色,目的是讓y的兄弟節點變爲黑色(旋轉後y的兄弟節點變成了b的左孩子,是黑色的)。
狀況2,y的兄弟節點b是黑色,b的兩個孩子都是黑色,這時咱們將y的兄弟節點b設置爲紅色,並將y攜帶的黑色傳遞給它的父親節點。(對於b的兩個孩子來講,其父親雖然變成了紅色,可是其祖父節點額外多了一個黑色,所以路徑上的黑色節點個數仍是不變。)這時其父親節點自己的顏色不定,若是自己是紅色的,那麼用<1. 處理,萬事,若是父親仍是黑色的,那麼仍是落入瞭如今討論的這幾種狀況中,繼續處理。
狀況3,y的兄弟節點b是黑色,b的左孩子是紅色,右孩子是黑色,y的父親節點顏色不定,這時對b作右旋,並交換b和其左孩子的顏色。目的是將y的兄弟節點的右孩子變爲紅色。
狀況4,y的兄弟節點b是黑色,b的右孩子是紅色,左孩子顏色不定,y的父節點顏色不定,這時對y的父親節點作左旋,並交換y和b的顏色。注意,對於y來講,父親節點到y的這條路徑上會多一個黑色節點,咱們恰好用y攜帶的那個黑色抵消,對於b到其右孩子這條路徑上會少一個黑色節點,咱們將b的右孩子由紅色設置爲黑色。完事,黑色被抵消掉了。
(關於父子的描述都是旋轉以前的關係,這樣更清楚一點。另外稍微分析一下旋轉操做以後如何交換節點顏色會保持幾個路徑上的黑色節點數量不變,這一點應該不難)。算法
狀況1在向狀況3和4轉變,狀況2在向<1, <2和狀況3和4轉變,狀況3在向狀況4轉變,而狀況4條件下經過一次旋轉能夠抵消掉這個黑色。把握住這個核心邏輯。搜索