定义
红黑树:一种特殊的二叉搜索树
二叉搜索树:一种树的类型,每个节点最多有两个子节点,其中其左节点一定小于当前节点,右节点一定大于当前节点
二叉树的缺点:如果给定的初始序列顺序不好,可能会建出类似于链表的结构,对搜索速度全无助益
红黑树的目的:构建一棵趋于平衡的二叉搜索树,杜绝bad case的出现情况
性质
红黑树树节点的组成
- 左孩子 left (树节点)
- 右孩子 right (树节点)
- 父节点 parent (树节点)
- 颜色 color (红/黑)
- 值 value (任意)
红黑树的特点
- 没有一条路径会比其他路径长出2倍
合法红黑树的性质
- 每个节点都是红色或者黑色的
- 根节点是黑色的
- 叶节点*是黑色的
- 如果一个节点是红色的,他的两个孩子都应该是黑色的
- 对每个结点,从该节点到其所有后代的叶子节点的简单路径上,包含相同数目的黑色节点
其中,最后一个性质确保了红黑树的相对“平衡”
*为了便于处理边界条件,红黑树中没有节点的孩子会直接指向None,通过定义一个通用哨兵NIL来代指None
NIL's param settings
parent = None
color = BLACK
left = None
right = None
value = None
右图为红黑树的包含哨兵(nil)状态,为了方便,后图都将采用左图的方式绘制
基本操作(旋转)
旋转操作是红黑树的基本操作,旋转的示意图如下
旋转需要满足如下要求:
- 左旋:需要左旋的树节点,其右孩子不为NIL
- 右旋:需要右旋的树节点,其左孩子不为NIL
至于其他节点,由于存在哨兵NIL,变得易于处理,以左旋为例:
- 事先定义:旋转的节点为N,它的右孩子为R,R的左孩子为RL(是NIL也无所谓),其他节点不需要关注。
- S1:断开N和R
- S2:N的右孩子为RL
- S3:R的左孩子为N
下面给出左旋和右旋的python代码
def _left_rotate(self, node):
if node.right == self.nil:
print("can't left rotate")
return
right = node.right
parent = node.parent
isLeft = parent.left == node
if self.root == node:
self.root = right
if isLeft:
parent.left = right
else:
parent.right = right
right.parent = parent
node.right