前置知识:二叉搜索树
什么是二叉搜索树呢,二叉搜索树有几个很特别的性质
节点的左子树只包含小于当前节点的数
节点的右子树只包含大于当前节点的数
所有左子树和右子树自身必须也是二叉搜索树
根据这些性质,我们可以得出,对二叉搜索树进行中序遍历,相当于对树中节点做了一次升序排序
对树中节点做查找操作,平均的时间复杂度是O(logn),但是在特殊情况下,二叉查找树可能会退化成链表
可以看到,这种情况下,也是符合二叉搜索树的性质的,但是查找的时间复杂度就从O(logn)变成O(n)了,线性的时间复杂度在大数据的情况下是不能忍受的,那么如何保持O(logn)的平均时间复杂度呢?对了,就是平衡,当树的高度过高时,就会根据一系列操作进行平衡,来保证O(logn)的平均时间复杂度。
红黑树
首先,红黑树是一个自平衡的二叉搜索树,大家都知道红黑树和二叉搜索树最大的不同点就在于平衡,当红黑树的结构被破坏后,就会执行平衡操作,使查找的平均时间复杂度一直在O(logn),红黑树的平衡操作包括变色、左旋、右旋
红黑树的基本性质
树中节点不是黑色的就是红色的
根节点永远是黑色的
如果一个节点是红色的,那么它的子结点只能是黑色的,反之不一定
叶子节点一点是黑色的
从根节点到叶子节点,必须包含相同数量的黑色节点
插入的节点默认是红色的
平衡操作
什么时候执行平衡操作呢?
当不满足红黑树的性质时,就会执行平衡操作,一般是连续两个红色节点
变色
假设有如下红黑树,插入节点6
很明显它有两个连续的红色节点,需要执行平衡操作,那什么时候执行变色操作呢?
条件:假设当前节点是6,当前节点是红色节点,当前节点的父节点是红色节点,该节点的叔叔节点(图中表现是13,也就是父节点的兄弟节点)也是红色节点,就会执行变色操作
变色操作:将当前节点的父节点和叔叔节点变成黑色,当前节点的爷爷节点变成红色
左旋
文字解释,根据根节点进行左旋操作,分为以下三步
1、将根节点的左孩子提上来作为新的根节点
2、将老的根节点变成新根节点的左孩子
3、将新根节点的左孩子,变成老根节点的右孩子
上面执行完变色操作后,可以发现还是存在两个连续的节点,但是却不满足变色的条件,因为叔叔节点是黑色的,这里就可以执行左旋操作
条件:当前节点为红色节点,是当前节点的父亲节点也是红色节点,但是叔叔节点不是红色的,并且当前节点为右孩子
左旋操作:根据当前节点的父节点为根节点,进行旋转
右旋
文字解释,根据根节点进行右旋操作,分为以下三步
1、将根节点的右孩子提上来作为新的根节点
2、将老的根节点,作为新根节点的右孩子
3、将新根节点的右孩子,变成老根节点的左孩子
上面操作完成后,发现还是有两个连续的红色节点,但是却不满足变色和左旋操作,那就只能右旋操作
条件:当前节点为红色,并且当前节点的父节点也为红色,但叔叔节点是黑色的,并且该节点为左孩子
右旋:在右旋之前有个变色的操作,但不是前面说的变色,这里将当前节点的父节点变成黑色,当前节点爷爷节点变成红色,并且这里不再是和左旋一样按照父节点来进行右旋,右旋是按照爷爷节点为根节点来进行右旋操作