携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第10天,点击查看活动详情
红黑树
对于二叉搜索树,如果插入的数据是随机的,那么它就是接近平衡的二叉树,平衡的二叉树,它的操作效率(查询,插入,删除)效率较高,时间复杂度是O(logN)。但是可能会出现一种极端的情况,那就是插入的数据是有序的(递增或者递减),那么所有的节点都会在根节点的右侧或左侧,此时,二叉搜索树就变为了一个链表,它的操作效率就降低了,时间复杂度为O(N),所以可以认为二叉搜索树的时间复杂度介于O(logN)和O(N)之间,视情况而定。那么为了应对这种极端情况,红黑树就出现了,它是具备了某些特性的二叉搜索树,能解决非平衡树问题,红黑树是一种接近平衡的二叉树。
红黑树的特性
首先,红黑树是一个搜索树,它同时满足以下特性:
(1) 每个节点要么是黑色,要么是红色
(2) 根节点是黑色
(3) 如果节点是红色的,那么它的子节点必须是黑色的(反之,不一定需要成立)
(4) 从根节点到叶节点或空子节点的每条路径,都包含相同数目的黑色节
红黑树的效率
红黑树的查找,插入和删除操作,时间复杂度都是O(logN)。查找操作时,它和普通的相对平衡的二叉搜索树的效率相同,都是通过相同的方式来查找的,没有用到红黑树特有的特性。但,如果插入的时候是有序数据,那么红黑树的查询效率就比二叉搜索树要高了,因为此时二叉搜索树不是平衡树,它的时间复杂度O(N)。插入和删除操作时,由于红黑树的每次操作平均要旋转一次和变换颜色,所以它比普通的二叉搜索树效率要低一点,不过时间复杂度仍然是O(logN)。总之,红黑树的优点就是对有序数据的查询操作不会慢到O(logN)的时间复杂度。
旋转
在红黑树中,插入或者删除数据时,为了保持红黑树的那五个特性,需要进行旋转和变换颜色的操作。旋转必须要一次性做两件事情:
-
使一些节点上升,一些节点下降,帮助树平衡
-
保证不破坏二叉搜索树的特征
旋转分为左旋转和右旋转
左旋转
以50为支点进行逆时针旋转,然后75成为了顶点,50成为了75的左子节点,65成为了50的右子节点,这个操作就是左旋转。
右旋转
以75为支点顺时针旋转,然后50成为了顶点,75成为了50的右子节点,65成为了75的左子节点,这就是右旋转操作。
插入操作
在红黑树中,插入一个节点,都执行了哪些操作呢?
首先,查找要插入节点的位置,然后给予颜色(红色或者黑色),但是为了保证红黑树的特性,需要进行旋转或者更改颜色,需要注意的是,在旋转前和旋转后,红黑树一直都是一个二叉搜索树,二叉搜索树的特征从未改变过。
这里,对于新插入的节点,我们给予的颜色是红色,是因为为了和红黑树的第(4)条特性不冲突: 从根节点到叶节点或空子节点的每条路径,都包含相同数目的黑色节点。这样就少了很多操作。然后看其它几个特性
-
对于(1)特性:每个节点要么是黑色,要么是红色,不冲突。
-
对于(2)特性:根节点是黑色,如果插入的节点不是根节点,也不冲突。如果是根节点,那么直接给予颜色黑色
那么,唯一需要满足的特性就是(3):如果节点是红色的,那么它的子节点必须是黑色的。这里,当我们给予新插入的节点颜色是红色时,需要根据父节点的不同情况做不同的处理,以满足这个特性。