轉載自https://www.cnblogs.com/liyuan989/p/4071942.html
感覺寫的非常好
前言
紅黑樹是特殊二叉查找樹的一種,一棵紅黑樹有以下5種性質:
- 根節點為黑色。
- 每個節點不是黑色就是紅色。
- 每個紅色節點的兩個兒子一定是黑色。
- 所有的葉子節點都是黑色。(注:這里的葉子節點並不是真正意義上的葉子節點,而是一種只有顏色屬性但不存放數據的節點,而且其沒有兒子節點)
- 一個紅黑樹的中任取一個節點,從它所在位置到其他任何葉子節點的簡單路徑上所經過的黑色節點數相同。
這5個性質決定了從根節點到葉子節點的最長路徑不可能大於最短路徑的2倍。所以紅黑樹是一個大致平衡的二叉樹。跟AVL樹不同,紅黑樹並不是嚴格平衡的,而AVL樹卻是嚴格平衡的。
插入
首先約定插入的新節點的顏色都為紅色。然后將該節點插入的按二叉查找樹的規則插入到樹中。這個節點后文稱為N
1. 根節點為空。這種情況,將N的顏色改為黑色即可。
2. N的父節點為黑色。這種情況不需要做修改。
3. N的父節點為紅色(根據性質3,N的祖父節點必為黑色)。
- N的叔父節點為紅色。這種情況,將N的父節點和叔父節點的顏色都改為黑色,若祖父節點是跟節點就將其改為黑色,否則將其顏色改為紅色,並以祖父節點為插入的目標節點從情況1開始遞歸檢測。
- N的叔父節點為黑色, 且N和N的父節點在同一邊(即父節點為祖父的左兒子時,N也是父節點的左兒子。父節點為祖父節點的右兒子時。N也是父節點的右兒子)。以父節點為祖父節的左兒子為例,將父節點改為黑色,祖父節點改為紅色,然后以祖父節點為基准右旋。(N為父節點右兒子時做相應的左旋。)
- N的叔父節點為黑色,切N和N的父節點不在同一邊(即父節點為祖父的左兒子時,N是父節點的右兒子。父節點為祖父節點的右兒子時。N也是父節點左右兒子)。以父節點為祖父節點的左兒子為例。以父節點為基准,進行左旋,然后以父節點為目標插入節點進入情況3的b情況進行操作。
刪除
刪除的節點有兩個兒子時,可以轉化為刪除的節點只有一個兒子時的問題。對於二叉查找樹,在刪除帶有兩個非葉子兒子的節點的時候,我們找到要么在它的左子樹中的最大元素、要么在它的右子樹中的最小元素,並把它的值轉移到要刪除的節點中。我們接着刪除我們從中復制出值的那個節點,它必定有少於兩個非葉子的兒子。因為只是復制了一個值,不違反任何性質,這就把問題簡化為如何刪除最多有一個兒子的節點的問題。它不關心這個節點是最初要刪除的節點還是我們從中復制出值的那個節點。
那么所有情況都可以轉化為刪除只有一個兒子的節點的情況,我們約定這個要刪除的節點為N(若N“沒有”兒子節點,並用他的任意一個為葉子節點的兒子節點頂替即可)
1. N為紅色節點時。直接刪除N,用它的黑色兒子代替它的位置。
2. N為黑色節點,且父節點為紅色。直接刪除N,用它的兒子節點代替它的位置,並將該兒子節點改為黑色。
3. N為黑色節點,且父節點為黑色。我們之間刪除N,用它的兒子節點代替它,該兒子節點成為N',將N’的顏色改為黑色。
- N’的兄弟節點和兄弟節點的2個兒子都為黑色。交換兄弟節點和父節點的顏色即可。
- N‘的兄弟節點為黑色、且兄弟節點的紅色兒子和兄弟節點在一邊(即兄弟節點為左兒子時,紅色兒子也為左兒子。兄弟節點為右兒子時,紅色兒子也為右兒子)。我們以兄弟節點為右兒子為例。將祖父節點和兄弟節點的顏色互換,並將紅色右兒子的顏色改為黑色,然后以祖父節點為基准左旋。(若兄弟節點為左兒子,則相應的右旋)
- N‘的兄弟節點為黑色、且兄弟節點的紅兒子和兄弟節點不在一邊(即兄弟節點為左兒子時,紅色兒子也為右兒子。兄弟節點為右兒子時,紅色兒子也為左兒子)。我們以兄弟結點為右兒子為例。將兄弟節點和它的紅色兒子的顏色互換,然后以兄弟節點為基准右旋。此時對於N’來說就進入了上文b情況。(若兄弟節點為右兒子,則相應的左旋)
- N‘的兄弟節點為紅色。以兄弟節點為右兒子為例,將父節點和兄弟節點的顏色互換,然后以父節點為基准左旋(若兄弟節點為左兒子則相應的右旋),此N’有一個黑色的兄弟節點,接下來N就可以進入a、b、c三種情況分別操作了。
- N‘的兄弟節為黑色,父節點也為黑色。此時將兄弟節點的顏色改為紅色。然后以父節點為目標插入節點從頭開始依次判斷。