引用《平衡二叉树的插入旋转》的这篇 ,多加了些注释;
平衡二叉树定义(AVL):它或者是一颗空树,或者具有以下性质的二叉树:它的左子树和右子树的深度之差的绝对值不超过1,且它的左子树和右子树都是一颗平衡二叉树。
最小不平衡子树:指离插入节点最近且以平衡因子的绝对值大于1的节点作为根的子树。
平衡因子(bf):结点的左子树的深度减去右子树的深度,那么显然-1<=bf<=1;
插入操作
在平衡二叉树中插入结点与二叉查找树最大的不同在于要随时保证插入后整棵二叉树是平衡的。那么调整不平衡树的基本方法就是: 旋转,基本思路都是转换到左旋和右旋。
旋转满足二叉树的平衡性情况分单旋转和双旋转,单旋转是针对于左左和右右这两种情况的解决方案,这两种情况是对称的,只要解决了左左这种情况,右右就很好办了。看下面的右旋例子;
1) 右旋: 在最小平衡子树根节点平衡因子>=2且在根节点的左孩子的左孩子插入元素,进行右旋
这是左左的情况,围着80旋转,80大于70,所以可以作为70的右节点,而75大于70,所以可以作为70的左节点;
2) 左旋: 在最小平衡子树根节点平衡因子>=-2且在根节点的右孩子的右孩子插入元素,进行左旋。
这种情况是右右,围着80左旋,80小于100,所以做100的左孩子,90大于80,所以做80的右孩子;
3) 右左:最小平衡子树根节点(80)的右孩子(100)的左孩子(90)的子节点(95)插入新元素,先绕根节点的右孩子节点(100)右旋,再围根节点(80)左旋
//这种情况和单旋转的没有太大差别,也很好理解了。
4) 左右:在最小平衡子树根节点(80)的左孩子(50)的右孩子(70)的子节点插入新元素,先绕根节点的左孩子节点(50)右旋,再围根节点(80)左旋