什么是红黑树?(Red-Black Tree)
红黑树是一种自平衡的二叉查找树,它可在 O(logN) 时间内完成查找、增加、删除等操作
红黑树的性质
红黑树通过以下性质的定义来实现自平衡
- 根是黑色
- 叶子节点都是黑色
- 红色节点不能连续
- 某节点到其叶子节点的黑色数量相同
所以
- 当某条路径最短时,必然都是黑色节点
- 当某条路径长度最长时
- 必然是由红、黑节点相间(性质3)
- 路径上红色节点数量 = 黑色节点数量(性质4)
- 路径长度为两倍黑色节点数量,也是最短路径长度的2倍
平衡树的左右旋
这里补充一个平衡树的旋转操作
为了减小树的高度,平衡二叉树会采取左右旋转
左旋
Left Rotate
right = n.right //临时保存
n.right = right.left
right.left = n
右旋
Right Rotate(13)
left = n.left //临时保存
n.left = left.right
left.right = n
红黑树的插入
红黑树的插入永远是红色节点,然后再根据性质做调整;(如果插入的是黑色节点,调整起来较为复杂)
红黑树的插入根据情况进行调整
1. 插入根节点
插入「13」,根据性质1(根节点为黑色),转为黑色
2. 插入时,父节点为黑色
插入「8」和「17」,满足性质,无需调整
3. 插入时,父节点为红色,父节点的兄弟节点也是红色
插入「15」,
根据性质3(红色节点不能连续),将父节点「17」转为黑色
根据性质4(到叶子节点的黑色数量相同),将父节点的兄弟节点「8」转为黑色
4. 插入时,父节点为红色,父节点的兄弟节点是黑色或者父节点没有兄弟节点
插入「14」,
根据性质3(红色节点不能连续),将父节点「15」转为黑色
根据性质4(到叶子节点的黑色数量相同),需要将父节点「15」进行旋转(右旋)
或者,插入「16」,
红黑树的删除
- 要删除的节点有兄弟节点:
1. 先找到该节点的prefix(该节点左子树中最大的节点)或者suffix(该节点右子树中最小的节点)
2. 将前驱或者后继的值复制到要删除的节点中,最后再将前驱或后继删除
前驱和后继至多只有一个孩子节点,这样就把原来要删除的节点有两个孩子的问题转化为只有一个孩子节点的问题,简化了问题
- 删除的节点没有兄弟节点
删除节点后,再根据性质调整红黑树