红黑树:
性质!
1、每个节点要么是黑色,要么是红色。(节点非黑即红)
2、根节点是黑色。
3、每个叶子节点(NULL)是黑色(为了简单期间,一般会省略该节点)。
4、如果一个节点是红色的,则它的子节点必须是黑色的。(也就是说父子节点不能同时为红色)
5、从一个节点到该节点的每一个叶子子孙节点的所有路径上包含相同数目的黑节点。(这一点是平衡的关键)
6、新插入节点默认为红色,插入后需要校验红黑树是否符合规则,不符合则需要进行操作。
插入(插入节点的颜色是红色):
(1)新节点位于根节点,其没有父节点时,处理思路:将该节点直接设为黑色即可
(2)新节点的父节点已然是黑色时,处理思路:不用动,这已然是一颗红黑树
(3)父节点和叔节点都是红色时,处理思路:a.将父节点和叔节点设为黑色;b.将祖父节点设为红色;c.将祖父节点设为当前节点,并继续对新当前节点进行操作。如果当前节点为根节点,则将其设置为黑色。
(4)父节点是红色,叔节点是黑色时,又分如下四种情况:
当前节点是父亲的左孩子,父亲是祖父的左孩子(Left-Left),处理思路:a.将祖父节点右旋;b.交换父节点和祖父节点的颜色
当前节点是父亲的右孩子,父亲是祖父的左孩子(Right-Left),处理思路:a.将父节点左旋,并将父节点作为当前节点; b.然后再使用Left Left情形
当前节点是父亲的右孩子,父亲是祖父的右孩子(Right-Right),处理思路:a.将祖父节点左旋;b.交换父节点和祖父节点的颜色
当前节点是父亲的左孩子,父亲是祖父的右孩子(Left-Right),处理思路:a.将父节点右旋,并将父节点作为当前节点; b.然后再使用Right Right情形
删除:
一、从树中删除节点X(以寻找后继节点的方式进行删除)
情况①:
1.1如果X没有孩子,且如果X是红色,直接删除X
1.2如果X是黑色,则以X为当前节点进行旋转调色,最后删掉X
请看下面的具体旋转调色方案
情况②:如果X只有一个孩子C,交换X和C的数值,再对新X进行删除。根据红黑树特性,此时X不可能为红色,因为红色节点要么没有孩子,要么有两个黑孩子。此时以新X为当前节点进行情况①的判断
此时直接删除55就ok了。
情况③:如果X有两个孩子,则从后继中找到最小节点D || 前驱中找到最大的值D,交换X和D的数值,再对新X进行删除。此时以新X为当前节点进行情况①或②的判断
二、旋转调色(N=旋转调色的当前节点[等于情况①中的X],P=N的父亲,W=N的兄弟,Nf=N的远侄子,Nn=N的近侄子)
情况1:N是根或者N是红色,则:直接将N设为黑色
情况2:N不是根且N是黑色,且W为红色,则:将W设为黑色,P设为红色,对P进行旋转(N为P的左子时进行左旋,N为P的右子时进行右旋),将情况转化为情况1、2、3、4、5
情况3:N不是根且N是黑色,且W为黑色,且W的左右子均为黑色,则:将W设为红色,将P设为当前节点进行旋转调色,将情况转化为情况1、2、3、4、5
情况4:N不是根且N是黑色,且W为黑色,且Nf为黑色,Nn为红色,则:交换W与Nn的颜色,并对W进行旋转(N为P的左子进行右旋,N为P的右子进行左旋),旋转后N的新兄弟W有一个红色WR,则转换为情况5
情况5:N不是根且N是黑色,且W为黑色,且Nf为红色,Nn为黑色,则:将W设为P的颜色,P和Nf设为黑色,并对P进行旋转(N为P的左子进行左旋,N为P的右子进行右旋)
此时,直接删除75节点就ok了