1、平衡二叉树(AVL):指二叉树中任意一个节点的左右子树的高度相差不能大于1
2、红黑树:近似平衡,高度近似为节点要么为红色,要么为黑色。同时,必须满足如下要求
- 根节点是黑色的
- 每个叶子节点都是黑色的空节点(NIL),即叶子节点不保存数据
- 任何相邻的节点不能同时为红色,即红色节点是被黑色节点隔开的
- 每个节点,从该节点到达其可达叶子节点的所有路径,都包含相同数目的黑色节点
3、左旋/右旋
4、插入操作的平衡调整:红黑树规定,插入的节点必须是红色的,而且,二叉查找树中新插入的节点都是放在叶子节点上
插入操作打破红黑树平衡,调整的三种情况:(个人简化描述:叔叔节点为父节点的兄弟节点;祖父节点为父节点的父节点;正在处理的节点称为关注节点)
(1)Case1:关注节点是a,他的叔叔节点d是红色。执行如下操作:
-
将关注点a的父节点b,叔叔节点d的颜色都设置成黑色;
-
将关注节点a的祖父节点c的颜色设置成红色;
-
关注节点变成a的祖父节点c;
-
跳到case2或者case3
(2)Case2:如果关注节点是a,他的叔叔节点d是黑色的,关注节点a是其父节点b的右子节点。则执行以下操作:
-
关注节点变成节点a的父节点b;
-
围绕新的关注节点b左旋;
-
跳到case3
(3)Case3:如果关注节点是a,他的叔叔节点d是黑色的,关注节点a是其父节点b的左子节点;则执行以下操作
-
围绕关注节点a的祖父节点C右旋
-
将关注节点a的父节点b,兄弟节点c的颜色互换
-
调整结束
5、删除操作的平衡调整
步骤一:针对删除节点初步调整,以满足从该节点到达其可达叶子节点的所有路径,都包含相同数目的黑色节点的要求
步骤二:针对关注节点进行二次调整,以满足不存在相邻的两个红色节点的要求
步骤一:针对删除节点初步调整(在这个步骤中,节点可能会被标记两种颜色)
(1)Case1:如果要删除的节点是a,他只有一个子节点b;则进行如下操作
-
删除节点a,并且把节点b替换到节点a的位置;
-
节点a只能是黑色,节点b也只能是红色,故需要把节点b改为黑色;
-
调整结束
(2)Case2:如果要删除的节点a有两个非空子节点,并且它的后继节点就是节点a的右子节点c;则进行如下操作
-
如果节点 a 的后继节点就是右子节点 c,那右子节点 c 肯定没有左子树。我们把节点 a 删除,并且将节点 c 替换到节点 a 的位置。
-
然后把节点 c 的颜色设置为跟节点 a 相同的颜色;
-
如果节点 c 是黑色,为了不违反叶子节点为黑色,我们给节点 c 的右子节点 d 多加一个黑色,这个时候节点 d 就成了“红 - 黑”或者“黑 - 黑”;
-
将关注节点变成节点 d,第二步的调整操作就会针对关注节点来做。.
(3)Case3:如果要删除的是节点a,他有两个非空子节点,并且节点a的后继节点不是右子节点;则进行如下操作
- 找到后继节点d,并将它删除,删除后继节点d的过程参照case1;
- 将节点a替换成后继节点d;
- 把节点d的颜色设置为跟节点a相同的颜色
- 如果节点d是黑色,为了不违反红黑树叶子节点为黑色的原则,我们给节点d的右子节点c多加一个黑色,此时节点c就成了“红-黑”或“黑-黑”;
- 将关注节点变成节点c,第二部的调整操作就会针对关注节点来做
步骤二:针对关注节点进行二次调整(解决红黑树中存在相邻红色节点的情况)
(1)Case1:如果关注节点是a,他的兄弟节点是红色的;则进行如下操作
- 围绕关注节点 a 的父节点 b 左旋;
- 关注节点 a 的父节点 b 和祖父节点 c 交换颜色;
- 关注节点不变;
- 继续从四种情况中选择适合的规则来调整。
(2)Case2:如果关注节点是 a,它的兄弟节点 c 是黑色,并且节点 c 的左右子节点 d、e 都是黑色;则进行如下操作:
- 将关注节点 a 的兄弟节点 c 的颜色变成红色;
- 从关注节点 a 中去掉一个黑色,这个时候节点 a 就是单纯的红色或者黑色;
- 给关注节点 a 的父节点 b 添加一个黑色,这个时候节点 b 就变成了“红 - 黑”或者“黑 - 黑”;
- 关注节点从 a 变成其父节点 b;
- 继续从四种情况中选择符合的规则来调整。
(3)CASE 3:如果关注节点是 a,它的兄弟节点 c 是黑色,c 的左子节点 d 是红色,c 的右子节点 e 是黑色;则进行如下操作
- 围绕关注节点a的兄弟节点c右旋;
- 节点C和节点d交换颜色;
- 关注点不变
- 跳转到case4,继续调整
(4)Case4:如果关注节点a的兄弟节点c是黑色的,并且c的右子节点是红色的;则进行如下操作:
- 围绕关注节点a的父节点b左旋;
- 将关注节点a的兄弟节点c的颜色,跟关注节点a的父节点b设置成相同颜色;
- 将关注节点 a 的父节点 b 的颜色设置为黑色;
- 从关注节点 a 中去掉一个黑色,节点 a 就变成了单纯的红色或者黑色;
- 将关注节点 a 的叔叔节点 e 设置为黑色;
- 调整结束。
参考资料:极客时间《数据结构与算法之美》王争