红黑树是平衡二叉树的一个变种。
一、 产生平衡二叉树的原因。
二叉搜索树的问题在于极端场景下退化为类似链表的结构,所以搜索的时间复杂度就变成了O(N)。为了保证二叉树不退化为链表,我们必须保证二叉树的的平衡性。
二叉平衡搜索树就是解决上面的问题的。就是AVL树和红黑树
拓展就是多叉平衡二叉树,那就是B树系列。然后哈希表也可以搜索。
二、二叉平衡树的概念。
当二叉搜索树中插入新节点后,如果能保证每个节点的左右子树高度只差的绝对值不超过1.即可降低树的高度,从而减少平均搜索的长度
一棵AVL树或者空树,或者是具有以下性质的二叉搜索树
它的左右子树都是AVL树,左右子树高度之差(平衡因子)的绝对值不超过1。增删查改:高度次 -O(logN)
三、平衡二叉树的插入。
在插入时,我们可以先构造二叉搜索树。然后再进行平衡操作。
1、新增在左边,parent平衡因子要减减
2、新增在右边,parent平衡因子要加加
3、更新后parent平衡因子==0,说明parent所在的子树的高度不变,不会影响祖先,不用再继续沿着到root的路径往上更新。插入完成
4、更新后parent平衡因子==负1or1,说明parent所在的子树的高度变化,会影响祖先,再继续沿着到root的路径往上更新。
5、更新后parent平衡因子 == 2or负2,说明parent所在的子树的高度变化且不平衡。对parent所在子树进行旋转,让它平衡。插入结束。
6、更新到根节点也是一种插入结束的情况。那么如何进行平衡呢
我们这里需要用到旋转平衡。
旋转的时候需要注意的问题。
1、保持它是搜索树
2、变成平衡树且降低整棵树的高度
左单旋:
核心操作就是parent->right = cur->left;cur->left = parent;
这么做的原因是:cur->left一定比parent要大。然后放在parent的右边是符合搜索树的定义的。
注意要修改父亲,还要注意curleft为空的情况。修改平衡因子。还有要把子树跟原来的树连接
如果是独立的树 parent == _root,进行parent->_parent置空。
如果不是独立的树我们需要对parent->_parent进行保存为ppnode,然后进行判断子树是属于ppnode的左子树还是右子树修改ppnode的左右子树为cur,然后修改cur的父亲指针。
抽象图的解释:
插入之前abc为符合AVL规则的子树。 无论是哪种情况,我们的旋转过程是不变的。插入前的AVL树有无数种情况,我们需要使用抽象图来表示。
双旋:
分为先左后右,先右后左
上面只是先右后左的图片。