1.基础
(基础)二叉排序树(Binary Sort Tree),又称二叉查找树(Binary Search Tree),也称二叉搜索树
2.AVL树出现的背景
(AVL树出现的背景)问题分析:
数组 {1, 2, 3, 4, 5, 6} ,对应的二叉排序树(BST)的问题所在
(1)左子树全部为空,从形式上看,更像一个单链表
(2)插入速度没有影响
(3)查询速度明显降低(因为需要依次比较),不能发挥BST的优势,因为每次还需要比较左子树,查询速度比单链表还慢
3.优化演变,解决BST查询带来的问题
(由基础优化演变而来,解决BST查询带来的问题)AVL树(以发明者G.M.Adelson-Velsky和E.M.Landis的名字命名),又称平衡二叉搜索树(Self-balancing binary search tree),也称平衡二叉树
AVL树特点:
(1)本身是一棵二叉排序树
(2)带平衡条件:每个结点的左右子树的高度差的绝对值不超过1,最多为1
AVL树本质就是带平衡功能的二叉排序树
平衡二叉树的实现方式有红黑树(算法)、AVL(算法)、替罪羊树、Treap、伸展树等
4.什么时候需要维护平衡二叉树的平衡?
二叉树进行节点的 添加 与 删除 的时候,都会破坏平衡二叉树的平衡,所以在二叉树添加节点完毕之后 与 二叉树删除节点完毕之后,都需要重新维护平衡二叉树的平衡
5.维护平衡二叉树平衡的方式之一
单向旋转之左旋转
添加一个节点之后,如果存在二叉树的任意一个节点的右子树的高度 减去 左子树的高度 所得的差大于 1 ,则需要把当前的二叉树通过左旋转的方式维护成平衡二叉树,即AVL树(递归的方式保证了任意一个节点的左右子树的高度差的绝对值不超过1)
左旋转的步骤
(1)创建一个新节点 newNode ,新节点的值等于当前节点的值(由于添加节点的代码存在递归,注意分析 当前节点 会有不同的指向)
(2)把新节点的左子树指向当前节点的左子树
newNode.left = this.left
(3)把新节点的右子树指向当前节点的右子树的左子树
newNode.right = this.right.left
(4)把当前节点的值设置为其右子节点的值
this.value = this.right.value
(5)把当前节点的右子树指向其右子树的右子树
this.right = this.right.right
(6)把当前节点的左子树指向新节点
this.left = newNode
图解左旋转的步骤
使用数组 {4, 3, 6, 5, 7, 8} 构造平衡二叉树的过程中,在添加 8 之前,二叉树中的任意一个节点的左右子树的高度差的绝对值不超过 1 ,即为 AVL树,当 添加 8 之后,得到如下二叉树,此时以 4 作为当前节点,它的右子树高度为 3 , 它的左子树高度为 1 ,即 3 - 1 = 2 > 1 ,该二叉树就不再是一棵平衡二叉树了,通过左旋转维护成平衡二叉树
(1)创建一个新节点 newNode ,新节点的值等于当前节点的值(由于添加节点的代码存在递归,注意分析 当前节点 会有不同的指向)
(2)把新节点的左子树指向当前节点的左子树
newNode.left = this.left
(3)把新节点的右子树指向当前节点的右子树的左子树
newNode.right = this.right.left
(4)把当前节点的值设置为其右子节点的值
this.value = this.right.value
(5)把当前节点的右子树指向其右子树的右子树
this.right = this.right.right
(6)把当前节点的左子树指向新节点
this.left = newNode
最后通过左旋转得到的平衡二叉树,即AVL树,如下
6.维护平衡二叉树平衡的方式之二
单向旋转之右旋转
添加一个节点之后,如果存在二叉树的任意一个节点的左子树的高度 减去 右子树的高度 所得的差大于 1 ,则需要把当前的二叉树通过右旋转的方式维护成平衡二叉树,即AVL树(递归的方式保证了任意一个节点的左右子树的高度差的绝对值不超过1)
右旋转的步骤
(1)创建一个新节点 newNode ,新节点的值等于当前节点的值(由于添加节点的代码存在递归,注意分析 当前节点 会有不同的指向)
(2)把新节点的右子树指向当前节点的右子树
newNode.right = this.right
(3)把新节点的左子树指向当前节点的左子树的右子树
newNode.left = this.left.right
(4)把当前节点的值设置为其左子节点的值
this.value = this.left.value
(5)把当前节点的左子树指向其左子树的左子树
this.left = this.left.left
(6)把当前节点的右子树指向新节点
this.right= newNode
图解右旋转的步骤
使用数组 {10, 12, 8, 9, 7, 6} 构造平衡二叉树的过程中,在添加 6 之前,二叉树中的任意一个节点的左右子树的高度差的绝对值不超过 1 ,即为 AVL树,当 添加 6 之后,得到如下二叉树,此时以 10 作为当前节点,它的左子树高度为 3 , 它的右子树高度为 1 ,即 3 - 1 = 2 > 1 ,该二叉树就不再是一棵平衡二叉树了,通过右旋转维护成平衡二叉树
(1)创建一个新节点 newNode ,新节点的值等于当前节点的值(由于添加节点的代码存在递归,注意分析 当前节点 会有不同的指向&#