基本数据结构之红黑树

红黑树

红黑树(Red-Black Tree,R-B Tree)是一种自平衡的二叉查找树。在红黑树的每个节点上都多出一个存储位表示节点的颜色,颜色只能是红(Red)或者黑(Black)。

是根据AVL树进化而来的,由于AVL树每次插入都需要动态调整,这需要大量的时间,因此出现了红黑树。

红黑树不会像AVL树那样,每次插入都需要动态调整。因此当数据经常变化的时候,红黑树的效率要比AVL树要高。

红黑树的特性

红黑树的特性如下。
◎ 每个节点或者是黑色的,或者是红色的。
◎ 根节点是黑色的。
◎ 每个叶子节点(NIL)都是黑色的。(叶子节点全是空指针)
◎ 如果一个节点是红色的,则它的子节点必须是黑色的。(不红红)
◎ 从一个节点到该节点的子孙节点的所有路径上都包含相同数量(黑路同)
的黑色节点。
具体的数据结构如图4-15所示:

基本数据结构之红黑树_第1张图片

红黑树的左旋

对a节点进行左旋,指将a节点的右子节点设为a节点的父节点,即将a节点变成一个左节点。因此左旋意味着被旋转的节点将变成一个左节点,具体流程如图 4-16所示。

基本数据结构之红黑树_第2张图片

大家注意看 d: 节点左旋之前挂在b上,左旋之后挂在节点a上,经历了一个重新挂枝的过程。

红黑树的右旋

对b节点进行右旋,指将b节点的左子节点设为b节点的父节点,即将b节点设为一个右节点。因此右旋意味着被旋转的节点将变成一个右节点,具体流程如图 4-17所示:

基本数据结构之红黑树_第3张图片

红黑树的添加

红黑树的添加分为 3步:①将红黑树看作一颗二叉查找树,并以二叉树的插入规则插入新节点;②将插入的节点涂为“红色”或“黑色”;③通过左旋、右旋或着色操作,使之重新成为一颗红黑树。根据被插入的节点的父节点的情况,可以将具体的插入分为3种情况来处理。
(1)如果被插入的节点是根节点,则直接把此节点涂为黑色的。
(2)如果被插入的节点的父节点是黑色的,则什么也不需要做,在节点插入后,仍然是红黑树。
(3)如果被插入的节点的父节点是红色的,则在被插入节点的父节点是红色的时,被插入节点一定存在非空祖父节点,即被插入节点也一定存在叔叔节点,即使叔叔节点(叔叔节点指当前节点的祖父节点的另一个子节点)为空,我们也视之为存在,空节点本身就是黑色节点。然后根据叔叔节点的颜色,在被插入节点的父节点是红色的
时,进一步分为3种情况来处理。
◎ 如果当前节点的父节点是红色的,当前节点的叔叔节点是红色的,则将父节点设为黑色的,将叔叔节点设为黑色的,将祖父节点设为红色的,将祖父节点设为当前节点。
◎ 如果当前节点的父节点是红色的,当前节点的叔叔节点是黑色的且当前节点是右节点,则将父节点设为当前节点,以新节点为支点左旋。
◎ 如果当前节点的父节点是红色的,当前节点的叔叔节点是黑色的且当前节点是左节点,则将父节点设为黑色的,将祖父节点设为红色的,以祖父节点为支点右旋。

红黑树的删除

红黑树的删除分为两步:①将红黑树看作一颗二叉查找树,根据二叉查找树的删除规则删除节点;②通过左旋、旋转、重新着色操作进行树修正,使之重新成为一棵红黑树,具体操作如下。
(1)将红黑树看作一颗二叉查找树,将节点删除。
◎ 如果被删除的节点没有子节点,那么直接将该节点删除。
◎ 如果被删除的节点只有一个子节点,那么直接删除该节点,并用该节点的唯一子节点替换该节点的位置。
◎ 如果被删除的节点有两个子节点,那么先找出该节点的替换节点,然后把替换节点的数据复制给该节点的数据,之后删除替换节点。
(2)通过左旋、旋转、重新着色操作进行树修正,使之重新成为一棵红黑树,因为红黑树在删除节点后可能会违背红黑树的特性,所以需要通过旋转和重新着色来修正该树,使之重新成为一棵红黑树:
①如果当前节点的子节点是“红+黑”节点,则直接把该节点设为黑色的;

②如果当前节点的子节点是“黑+黑”节点,且当前节点是根节点,则什么都不做;③如果当前节点的子节点是“黑+黑”节点,且当前节点不是根节点,则又可以分为以下几种情况进行处理。
◎ 如果当前节点的子节点是“黑+黑”节点,且当前节点的兄弟节点是红色的,则将当前节点的兄弟节点设置为黑色的,将父节点设置为红色的,对父节点进行左旋,重新设置当前节点的兄弟节点。
◎ 如果当前节点的子节点是“黑+黑”节点,且当前节点的兄弟节点是黑色的,兄弟节点的两个子节点也都是黑色的,则将当前节点的兄弟节点设置为红色的,设置当前节点的父节点为新节点。
◎ 如果当前节点的子节点是“黑+黑”节点,且当前节点的兄弟节点是黑色的,兄弟节点的左子节点是红色的且右子节点是黑色的,则将当前节点的左子节点设置为黑色的,将兄弟节点设置为红色的,对兄弟节点进行右旋,重新设置当前节点的兄弟节点。
◎ 如果当前节点的子节点是“黑+黑”节点,且当前节点的兄弟节点是黑色的,兄弟节点的右子节点是红色的且左子节点是任意颜色的,则将当前节点的父节点的颜色赋值给兄弟基点,将父节点设置为黑色的,将兄弟节点的右子节点设置为黑色的,对父节点进行左旋,设置当前节点为根节点。

总结

若红红,看叔节点脸色:
(1)红叔,爷叔父节点染色,爷变为新节点

(2)黑叔,此时需要旋转+染色体

旋转:

(1)若LL型,右旋;爷父换位并染色

(2)若RR型,左旋;爷父换位并染色

(3)若LR型,先左后右,爷儿换位并染色

(4)若RL型,先右后左,爷儿换位并染色

你可能感兴趣的:(数据结构,数据结构,b树,算法)