红黑树的五条性质
- 每个结点要么是红的,要么是黑的。
- 根节点是黑的。
- 每个叶节点是黑的(NIL指针)。
- 如果一个结点是红的,那么它的两个子节点是黑的。
- 任取一个点,它到所有它的子树上的NIL结点的路径上黑结点数目是相等的。
由性质5可以保证红黑树上的查找是 O(logn) O ( l o g n ) 的。
红黑树的插入
红黑树的插入参考了这篇文章。
假设插入的新结点的初始颜色是红色。设插入的结点是N,父节点是P,祖父节点是G,叔叔结点是U。
1. 如果一开始是空树,将其刷黑即可。
2. 如果P是黑色,则不会破坏红黑树的任何性质,无需调整。
3. 如果P是红色,则破坏了性质4,需要调整。
插入前该树是一棵合法的红黑树,因此根据性质4,G是黑色的。
(1)如果U也是红色。那么将U和P染成黑色,G染成红色,这样不会影响性质5,然后把U当成当前结点继续调整。
(2)如果U是黑色且N是P的右结点,将N-P左旋使得变成情况3。
(3)如果U是黑色且N是P的左结点,将N-P-G右旋,且将G染成红色,P染成黑色,使之不违反性质5和性质2。
红黑树的删除
红黑树的删除参考了维基百科。
若要删的结点是叶子结点(即两个儿子都是NIL),我们将其中任意一看成它的儿子。
若要删除的结点有两个非NIL儿子,可以用它的直接前继(通常是它左子树的右下角那个结点)或者它的直接后继(通常是它右子树左下角那个结点)的值来代替它,然后删除这个用来代替的结点。这个结点显然不会有2个非NIL儿子。
这样我们要讨论的就是删除只有一个叶子结点的这个结点的情况。
如果该结点是红色,那么删除它不会影响红黑树的任何性质。
如果该结点是黑色,且它的儿子是红色,将该结点删去,儿子结点刷黑即可。
因此剩下的就只有该结点和儿子都是黑色的情况。
我们把要删除结点的儿子替换要删除的结点。称呼其为N,它的父亲为P,兄弟为S。
1. 如果N是根,则不需要任何其它操作,因为这相当于从所有路径上删除一个黑结点。
2. 如果S是红色,此时P肯定是黑色,将N-P-S左旋,这样每条路径上的黑结点数目和调整前相同,此时N有了一个黑色 的兄弟,继续根据4,5,6调整。
3. 如果S和S的儿子是黑色,P也是黑色,将S涂红,这样以P为根的子树符合所有性质,但P祖先的性质不符合了,此时需要在P上重新回到1进行调整。
4. 如果S和S的儿子是黑色,P是红色,则将P涂黑,S涂红,这样满足了所有性质。
5. 如果S是黑色,S的左儿子是红色,右儿子是黑色,且N是P的左儿子,我们将S右旋,将S涂红,S的左儿子涂黑,这样每条路径的值并没发生修改,但是P有了一个黑色右儿子且右儿子为红,进入6继续调整。
6. 如果S是黑色,其右儿子是红色,且N是P的左儿子,此时将P左旋,将P和S的颜色调换,可以保证满足性质5。