二叉搜索树(二叉排序树)的缺点
当我们插入的数据为1,2,3,4时,我们选择二叉搜索树来存放数据,那么存放的树的结构将是
在这种情况下,如果我们需要找到节点值为4的时候,需要查找四次,即时间耗费为O(N),远低于预期O(logN).
因此在这种时候,我们需要新的数据结构----平衡二叉树
平衡二叉树的概念
它是一 棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树.意思是说不管从整颗树来看,它的左右子树的高度差不能超过1,还是从深入到每个最细小的子树,其左右子树的高度也都不能超过1.
上面2颗树都是二叉搜索树,但是只有左边的一棵树是平衡二叉树,右边的树从节点7算的话,它的左子树高度为3,右子树高度为1,差值为2,不符合平衡二叉树的要求.
平衡二叉树的插入
假如说现在要插入6到上面图中的左边的平衡树里,插入结果为
可以明显的看到,插入6之后,这个树已经不是一个平衡二叉树了.这个时候,我们需要将树做一些旋转,来将树继续变为平衡二叉树.
在插入新节点后,只有那些从插入节点到根节点路径上的节点的平衡可能被改变,因为只有这些节点的子树可能会发生变化.当我们沿着这条路径上行到根并更新平衡信息时,可以发现一个节点,他的节点破坏了AVL条件.后面将重点解释上行时,第一个被破坏的点,以这个点为根基,来进行选择操作.
我们把需要平衡的点叫做α,由于每个节点最多只有2个儿子,因此出现高度不平衡就需要α的左右子树高度差为2,容易看出,出现这种情况的只有下面四种可能
1 对α左子树的左子树进行一次插入
2 对α的左子树的右子树进行一次插入
3 对α的右子树的左子树进行一次插入
4 对α的右子树的右子树进行一次插入
上面四种情况,1和4是镜像对称,2和3是进行对称.
第一种情况是插入发生在外边即(左-左,右-右的情况),该种情况通过对树进行一次单旋转即可实现平衡树
第二种情况是插入发生在内部,该情况通过稍微复杂的双旋转来处理
单旋转之右旋转
上图中,8这个节点是离新插入节点6的一个最近的非平衡节点,就以8为基准点来进行右旋
,左图中的尖尖的虚线,表示一种构想出来的壁垒,不允许节点跨越,便于理解怎么旋转变化.
变换后的二叉树明显就是一个平衡二叉树了.这就是单旋转之右旋转
单旋转之左旋转
当上面图中,插入9后,是个平衡树,再接着插入10,变为如下的不平衡树
这个时候在节点8补平衡了,这个时候需要左旋转
旋转后,变为右侧的图,实现平衡.这就是单旋转之左旋转.
双旋转之右-左双旋转
如上图所示,在插入节点15之后,在节点7处,出现了不平衡,因此需要旋转.但是这种情况不属于单旋转的情况,符合上面讲的四种情况的第三张情况,即双旋转.
先在α的儿子节点与孙子节点处旋转,再在α与其新儿子节点处旋转,实现双旋转
按照上面说的,先在α的儿子与孙子节点处旋转,示意图如下
这个时候就类似于第二种情况,即右右情况,这个时候再按照左旋转即可实现平衡,示意图如下
这就是双旋转之右-左双旋转
双旋转之左-右双旋转
如下图所示的一个二叉树
此时在最后插入9之后,节点10处出现不平衡,那么就以节点10为基准点即α,进行双旋转
1 先在α的儿子(8)与孙子(9)处进行旋转,
左旋后,如上图右侧所示
2 再在α与其新儿子处进行旋转
最终实现了平衡,这就是双旋转的左-右双旋转