特征
- 所有的节点必须是红节点或黑节点
- 根节点是黑色
- 每个空叶子节点(不同于二叉搜索树,红黑树的叶子节点均为空,即只有黑颜色属性,无其他属性)为黑色
- 红节点的子节点为黑色(即:不能连续两个父子节点均为红节点)
- 从任意节点到其叶子节点经过的路径的黑节点数相同,即拥有相同的黑路径
插入
首先根据二叉搜索树的插入方式找到要插入的位置,然后将新插入的节点标为红色。此处约定:要插入的节点为N,N的父节点为P,N的祖父节点(即P的父节点)为G,N的叔父节点(即P的兄弟节点)为U。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| start=>start: Start hasFather=>condition: 有无父节点P isFatherNodeColorRed=>condition: 父节点P为红色 isUncleNodeColorBlack=>condition: 叔父节点U为黑色 isNewNodeInside=>condition: 节点N是否在树的内侧 (G[左] - > P[右] - > N 或G[右] - > P[左] - > N) handleCase4_1=>operation: 对P进行左旋转或右旋转 左旋:G[左] - > P[右] - > N 右旋:G[右] - > P[左] - > N 旋转完后,P在树的外侧,即 G[左] - > N[左] - > P 或G[右] - > N[右] - > P 将P当成N,N当成P handleCase4_2=>operation: 对G进行左旋转或右旋转 右旋:G[左] - > P[左] - > N 左旋:G[右] - > P[右] - > N 将父节点、祖父节点颜色反转 (即P改为黑色,G改为红色) handleCase3=>operation: 将父节点、叔父节点、祖父节 点颜色反转(即P改为黑色, U改成黑色,G改为红色) 将G当成新插入的节点N handleCase1=>operation: 将节点N颜色变为黑色 handleCase2=>operation: 直接插入不用其他处理 end=>end: End
start->hasFather hasFather(yes)->isFatherNodeColorRed isFatherNodeColorRed(yes)->isUncleNodeColorBlack isUncleNodeColorBlack(no)->handleCase3->hasFather isUncleNodeColorBlack(yes)->isNewNodeInside isNewNodeInside(yes)->handleCase4_1->handleCase4_2->end isNewNodeInside(no)->handleCase4_2 hasFather(no)->handleCase1->end isFatherNodeColorRed(no)->handleCase2->end
|
删除
类似二叉搜索树,先找到要删除的数所在的节点V,对以这个节点为根节点的左子树进行搜索找到左子树的最大值所在的节点N(此处均以N在V的左子树进行讨论),将N节点的值覆盖到V节点上,然后将N节点进行删除。根据二叉搜索树的定义,可知,N节点最多有一个非叶子节点,对于搜索二叉树而言,直接删除N节点,将N节点的父节点P指向N节点即可。对于红黑树而言,除了执行跟搜索二叉树一样的操作外,还需要进行额外的调整使得整颗树仍然符合红黑树的特征,以下是进行调整的过程,约定如下:
- N:要删除的节点
- C:要删除的节点的子节点(排除另一个必为叶子的子节点,此子节点可能为叶子节点也可能非叶子节点)
- P:要删除的节点的父节点
- S:要删除的节点的兄弟节点
- SL:要删除的节点的兄弟节点的左节点
- SR:要删除的节点的兄弟节点的右节点
- 每一轮循环都根据N重新计算C、P、S、SL、SR节点
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| start=>start: Start isNodeBlack=>condition: N为黑色 isChildBlack=>condition: C为黑色 isChildLeaf=>condition: C为叶子节点 handleCase1=>operation: C颜色改为黑色 isNodeNotRoot=>condition: N非根节点 isSiblingNodeBlack=>condition: S节点为黑色 handleCase2=>operation: 反转P和S的颜色 (P为红,S为黑), 左旋或右旋P isSRNodeBlack=>condition: SR为黑色 handleCase3=>operation: 将P和S颜色对换, SR设为黑色,旋转 P让S成为P的父节点 isSLNodeBlack=>condition: SL为黑色 handleCase4=>operation: 旋转S让SL成为S的父节点 isParentNodeRed=>condition: P节点为红色 handleCase5=>operation: P改成黑色, S改成红色 handleCase6=>operation: S改成红色, 将P当成N (P = N) end=>end: End end1=>end: End end2=>end: End
start->isNodeBlack isNodeBlack(no)->end1 isNodeBlack(yes)->isChildLeaf isChildLeaf(no)->handleCase1->end isChildLeaf(yes)->isNodeNotRoot isNodeNotRoot(yes)->isSiblingNodeBlack isNodeNotRoot(no)->end2 isSiblingNodeBlack(no)->handleCase2->isNodeNotRoot isSiblingNodeBlack(yes)->isSRNodeBlack isSRNodeBlack(no)->handleCase3->end isSRNodeBlack(yes)->isSLNodeBlack isSLNodeBlack(no)->handleCase4->isNodeNotRoot isSLNodeBlack(yes)->isParentNodeRed isParentNodeRed(yes)->handleCase5->end isParentNodeRed(no)->handleCase6->isNodeNotRoot
|
参考资料
https://www.cnblogs.com/qingergege/p/7351659.html
https://en.wikipedia.org/wiki/Red–black_tree