轉載自https://www.cnblogs.com/liyuan989/p/4071942.html
感受寫的很是好html
前言
紅黑樹是特殊二叉查找樹的一種,一棵紅黑樹有如下5種性質:htm
- 根節點爲黑色。
- 每一個節點不是黑色就是紅色。
- 每一個紅色節點的兩個兒子必定是黑色。
- 全部的葉子節點都是黑色。(注:這裏的葉子節點並非真正意義上的葉子節點,而是一種只有顏色屬性但不存放數據的節點,並且其沒有兒子節點)
- 一個紅黑樹的中任取一個節點,從它所在位置到其餘任何葉子節點的簡單路徑上所通過的黑色節點數相同。
這5個性質決定了從根節點到葉子節點的最長路徑不可能大於最短路徑的2倍。因此紅黑樹是一個大體平衡的二叉樹。跟AVL樹不一樣,紅黑樹並非嚴格平衡的,而AVL樹倒是嚴格平衡的。blog
插入
首先約定插入的新節點的顏色都爲紅色。而後將該節點插入的按二叉查找樹的規則插入到樹中。這個節點後文稱爲N遞歸
1. 根節點爲空。這種狀況,將N的顏色改成黑色便可。二叉樹
2. N的父節點爲黑色。這種狀況不須要作修改。im
3. N的父節點爲紅色(根據性質3,N的祖父節點必爲黑色)。數據
- N的叔父節點爲紅色。這種狀況,將N的父節點和叔父節點的顏色都改成黑色,若祖父節點是跟節點就將其改成黑色,不然將其顏色改成紅色,並以祖父節點爲插入的目標節點從狀況1開始遞歸檢測。
![情形3 示意圖](http://static.javashuo.com/static/loading.gif)
- N的叔父節點爲黑色, 且N和N的父節點在同一邊(即父節點爲祖父的左兒子時,N也是父節點的左兒子。父節點爲祖父節點的右兒子時。N也是父節點的右兒子)。以父節點爲祖父節的左兒子爲例,將父節點改成黑色,祖父節點改成紅色,而後以祖父節點爲基準右旋。(N爲父節點右兒子時作相應的左旋。)
![情形5 示意圖](http://static.javashuo.com/static/loading.gif)
- N的叔父節點爲黑色,切N和N的父節點不在同一邊(即父節點爲祖父的左兒子時,N是父節點的右兒子。父節點爲祖父節點的右兒子時。N也是父節點左右兒子)。以父節點爲祖父節點的左兒子爲例。以父節點爲基準,進行左旋,而後以父節點爲目標插入節點進入狀況3的b狀況進行操做。
![情形4 示意圖](http://static.javashuo.com/static/loading.gif)
刪除
刪除的節點有兩個兒子時,能夠轉化爲刪除的節點只有一個兒子時的問題。對於二叉查找樹,在刪除帶有兩個非葉子兒子的節點的時候,咱們找到要麼在它的左子樹中的最大元素、要麼在它的右子樹中的最小元素,並把它的值轉移到要刪除的節點中。咱們接着刪除咱們從中複製出值的那個節點,它一定有少於兩個非葉子的兒子。由於只是複製了一個值,不違反任何性質,這就把問題簡化爲如何刪除最多有一個兒子的節點的問題。它不關心這個節點是最初要刪除的節點仍是咱們從中複製出值的那個節點。img
那麼全部狀況均可以轉化爲刪除只有一個兒子的節點的狀況,咱們約定這個要刪除的節點爲N(若N「沒有」兒子節點,並用他的任意一個爲葉子節點的兒子節點頂替便可)紅黑樹
1. N爲紅色節點時。直接刪除N,用它的黑色兒子代替它的位置。co
2. N爲黑色節點,且父節點爲紅色。直接刪除N,用它的兒子節點代替它的位置,並將該兒子節點改成黑色。
3. N爲黑色節點,且父節點爲黑色。咱們之間刪除N,用它的兒子節點代替它,該兒子節點成爲N',將N’的顏色改成黑色。
- N’的兄弟節點和兄弟節點的2個兒子都爲黑色。交換兄弟節點和父節點的顏色便可。
![情形4 示意圖](http://static.javashuo.com/static/loading.gif)
- N‘的兄弟節點爲黑色、且兄弟節點的紅色兒子和兄弟節點在一邊(即兄弟節點爲左兒子時,紅色兒子也爲左兒子。兄弟節點爲右兒子時,紅色兒子也爲右兒子)。咱們以兄弟節點爲右兒子爲例。將祖父節點和兄弟節點的顏色互換,並將紅色右兒子的顏色改成黑色,而後以祖父節點爲基準左旋。(若兄弟節點爲左兒子,則相應的右旋)
![情形6 示意圖](http://static.javashuo.com/static/loading.gif)
- N‘的兄弟節點爲黑色、且兄弟節點的紅兒子和兄弟節點不在一邊(即兄弟節點爲左兒子時,紅色兒子也爲右兒子。兄弟節點爲右兒子時,紅色兒子也爲左兒子)。咱們以兄弟結點爲右兒子爲例。將兄弟節點和它的紅色兒子的顏色互換,而後以兄弟節點爲基準右旋。此時對於N’來講就進入了上文b狀況。(若兄弟節點爲右兒子,則相應的左旋)
![情形5 示意圖](http://static.javashuo.com/static/loading.gif)
- N‘的兄弟節點爲紅色。以兄弟節點爲右兒子爲例,將父節點和兄弟節點的顏色互換,而後以父節點爲基準左旋(若兄弟節點爲左兒子則相應的右旋),此N’有一個黑色的兄弟節點,接下來N就能夠進入a、b、c三種狀況分別操做了。
![情形2 示意圖](http://static.javashuo.com/static/loading.gif)
- N‘的兄弟節爲黑色,父節點也爲黑色。此時將兄弟節點的顏色改成紅色。而後以父節點爲目標插入節點從頭開始依次判斷。
![情形3 示意圖](http://static.javashuo.com/static/loading.gif)