上一篇文章我们讲到了平衡二叉树的AVL树,本篇就介绍另一种平衡二叉树:红黑树(Red Black Tree)。
数据结构(一)、二叉树(BT),二叉查找树(BST),平衡二叉树(AVL树)
目录
简介
红黑树(Red Black Tree)是一种自平衡的二叉树,在插入和删除操作时可能会打破树的平衡,它会重新自处理以达到平衡状态。红黑树是复杂的,但它的操作有着良好的最坏情况运行时间,并且在实践中是高效的: 它可以在O(logn)时间内做查找,插入和删除,这里的n是树中元素的数目。
性质
红黑树是每个节点都带有颜色属性的二叉查找树,颜色为红色或黑色。在二叉查找树强制的一般性质以外还有下面几个性质:
- 节点是红色或黑色。
- 根是黑色。
- 所有叶子都是黑色(叶子是NIL节点)。
- 每个红色节点必须有两个黑色的子节点。(从每个叶子到根的所有路径上不能有两个连续的红色节点。)
- 从任一节点到其每个叶子的所有路径都包含相同数目的黑色节点。
新增的节点都是红色,然后对其他节点'变色'或'旋转'以达到平衡状态;
红黑树从根节点到叶子节点的最长路径不会超过最短路径的2倍;
下图是个红黑树的示例,为了简洁,在后面的内容中我们把Nil叶子节点省略:
自平衡
上面提到,当对红黑树中增删节点时若打破了红黑树的平衡条件时会将对该树做节点的'变色'和'旋转'操作,以重新达到平衡状态。
变色
下图是一个变色场景,给红黑树新增节点4和节点14,为了简洁,这里省略Nil叶子节点:
- 新增14节点后,由于新增节点都是红色,此时14和13节点是连续的红色节点,打破了规则4;
- 发生变色操作,13节点变为黑色,但此时由于12到14节点和12到20节点之间的黑色节点数量不一致,前者是3后者是2,打破了规则5;
- 于是20节点也变为黑色,此时该二叉树的右子树根节点到叶子节点的黑色节点数量为3,而左子树的根节点到叶子节点之间的黑色节点数量为2,再次打破了规则5;
- 于是节点16由黑色变成红色,此时红黑树恢复平衡状态;
- 对于新增的节点4,它的加入没有打破红黑树的平衡,所以直接就插入成功;
旋转
下图是一个 变色+旋转 场景,给红黑树新增节点9,为了简洁,这里省略Nil叶子节点:
(1). 变色:
- 插入节点9,将6,8父节点和叔节点变为黑色
- 祖父节点7变为红色
(2). 左旋转:
- 节点7的父节点5左旋作为7的左孩子
- 节点7升级为节点5的父节点
- 节点6转为节点5的右孩子
(3). 变色:
- 节点7变为黑色
- 根节点12变为红色
(4). 右旋转:
- 节点7的父节点12右旋为7节点的右孩子
- 节点7升级为根节点
- 节点8转为节点12的左节点
此时红黑树完成变色+旋转的操作,重新恢复平衡状态。
在线测试
由于红黑树理解起来比较复杂,这里也提供一个html附件,方便大家理解和使用,包含变色和旋转步骤:
希望本文对你有帮助,请点个赞鼓励一下作者吧~ 谢谢!