平衡二叉树也称之为AVL树,是一个具有以下特征的二叉搜索树:
1、左子树和右子树高度差不会大于1
2、左右两颗子树都满足第一个条件。
以下树,左边的高度为3,右边的高度为2,高度差为1,满足条件。
以下树,左边的高度为4,右边的高度为2,高度差大于1,不满足条件。
平衡二叉树是为了提高二叉树的查询速度。如果没有平衡二叉树,当我们给有序数据排序时,会产生一颗斜树,斜树是单链结构,失去查询速度快的优势。下面生成一颗斜树。
从图中可以看出,左斜树或者右斜树像是一个链表,插入和删除的速度依旧较快,但是查询的速度较慢,因为遍历深度更深,需要消耗更多的磁盘I/O操作。这个时候我们可以对其进行改造。
这个时候我们可以看出,平衡二叉树有了左子树和右子树,树的高度发生了变化,查询时候的磁盘I/O开销更小,速度更快。
平衡二叉树需要满足:左子树和右子树高度差不会大于1,如果大于1这个时候需要进行左旋转或右旋转。如下图二叉树就需要进行左旋转操作。
右旋转相反,不做过多的阐述。
1、获取当前二叉树的根节点,作为新节点并创建节点
2、获取当前二叉树的左子树,作为新节点的的左子树。
3、获取当前二叉树根节点的右子树的左节点,作为新节点的右子树。
4、获取当前二叉树右节点的值,作为新树的根节点。
5、获取当前二叉树右节点的右子树,作为新二叉树的右子树
案例中为了跟上面的案例达到一脉相承的效果,写了一个4.1,比较突兀,就是为了满足条件,大家可以使用权限的数字替代也行。
双旋转是基于单旋转(左旋、右旋),其只是对单旋转的代码调用,通过代码来理解双旋转即可。
双旋转代码的核心思想在于:在创建二叉树的过程中,每次添加新的节点,都要判断一下该二叉树是否需要旋转。
如果二叉树需要左旋,则先判断根节点的右子节点的左子树高度是否大于右子树的高度,如果大于则先对根节点的右子树进行右旋,最后再对原二叉树进行左旋;
如果二叉树需要右旋,则先判断根节点的左子节点的右子树高度是否大于左子树的高度,如果大于则先对根节点的左子树进行左旋,最后再对原二叉树进行右旋。
我们可以在对原二叉树右旋之前,将其右子树(以 6 为根节点的树)进行一次右旋即可。
然后再对整颗树进行左旋转