AVL树,也称平衡二叉搜索树,AVL是其发明者姓名简写。
AVL树属于树的一种,而且它也是一棵二叉搜索树,不同的是他通过一定机制能保证二叉搜索树的平衡,平衡的二叉搜索树的查询效率更高。
AVL树特点
-
AVL树是一棵二叉搜索树。
-
AVL树的左右子节点也是AVL树。
-
AVL树拥有二叉搜索树的所有基本特点。
-
每个节点的左右子节点的高度之差的绝对值最多为1,即平衡因子为范围为[-1,1]。
图中红色数字表示对应节点的高度,可以看到同一层的节点高度差都没有超过1。
二叉搜索树的平衡
基础的二叉搜索树构建出来可能会存在不平衡的现象,比如极端情况下,按照A B C D
顺序插入树中,结果为:
但实际上我们更想要平衡一点的二叉搜索树,因为平衡的二叉搜索树能有效提高查询效率,比如上面的要查询D节点则需要比较4个节点才找到,而平衡的二叉搜索树只需要比较3个节点。
所以AVL树的出现就是为了解决平衡性问题,它的核心内容就是平衡处理机制,即所谓的旋转,一共有四种形式的旋转:右单旋、左单旋、左右双旋和右左双旋。
为什么要旋转
不管是什么方式的旋转,旋转的目的是为了降低树的高度,使其平衡,假如树结构如下图,
将“A”节点添加到树中,变成如下结构,树产生了不平衡,于是检查哪里不平衡,当到“C”节点时发现高度差超过1,
所以需要对“C”节点进行右单旋操作将高度降到2,达到平衡。
插入方式
AVL树一共有四种插入方式,根据插入方式不同需要做不同的旋转操作,现在往下看四种插入方式,设受插入节点影响而失去平衡的节点的父节点为Z,
-
LL插入方式,插入的节点在Z节点的左子树的左子树上,如下图,“A”节点插入影响“C”节点的平衡,“C”的父节点为“E”,插入节点“A”在“E”节点(E节点为失去平衡的节点)的左子树的左子树上。即“B”节点的左右子节点都算LL插入。
-
RR插入方式,插入的节点在Z节点的右子树的右子树上,如下图,“I”节点插入影响“G”节点的平衡,“G”的父节点为“E”,插入节点“I”在“E”节点的右子树的右子树上。即“H”节点的左右子节点都算RR插入。
-
LR插入方式,插入的节点在Z节点的左子树的右子树上,如下图,“C”节点插入影响“B”节点的平衡,“B”的父节点为“E”,插入节点“C”在“E”节点的左子树的右子树上。即“D”节点的左右子节点都算LR插入。
-
RL插入方式,插入的节点在Z节点的右子树的左子树上,如下图,“G”节点插入影响“H”节点的平衡,“H”的父节点为“E”,插入节点“G”在“E”节点的右子树的左子树上。即“F”节点的左右子节点都算RL插入。
右单旋
右单旋用于处理LL插入方式,假设存在一棵树,现插入“A”节点,假如不进行旋转的话,树结构为下图,所以遍历过程也会检查哪里不平衡,检查到“C”节点和“G”节点的高度差大于1,而且插入节点“A”属于“E”节点左子树的左子树,于是进行右单旋,
“C”节点右单旋即将“C”节点提高,原本它的父节点“E”则变为其右子节点,“C”节点原来的右子节点则变为其父节点“E”的左子节点。右单旋后的结果如下,重新达到了平衡。
个人心得:这里的旋转保证的仍然是中序遍历的序列,原来CDE,旋转完后仍然是CDE,同时树达到了平衡。
左单旋
左单旋用于处理RR插入方式,假设存在一棵树,如下,现插入“I”节点,假如不进行旋转的话,树结构为下图,所以遍历过程也会检查哪里不平衡,检查到“C”节点和“G”节点的高度差大于1,而且插入节点“I”属于“E”节点的右子树的右子树,于是进行左单旋,
“G”节点左单旋即将“G”节点提高,原本它的父节点“E”则变为其左子节点,“G”节点原来的左子节点则变为其父节点“E”的右子节点。左单旋后的结果如下,重新达到了平衡。
个人心得:这里的旋转保证的仍然是中序遍历的序列,原来EFG,旋转完后仍然是EFG,同时树达到了平衡。
左右双旋
左右双旋用于处理LR插入方式,假设存在一棵树,如下,现插入“C”节点,假如不进行旋转的话,树结构为下图,遍历过程会检查哪里不平衡,检查到“B”节点和“G”节点的高度差大于1,而且插入节点“C”属于“E”节点的左子树的右子树,于是进行左右双旋,
先以“D”节点为轴进行左单旋,结果为,
再以“D”节点为轴进行右单旋,得到最终结果,
右左双旋
右左双旋用于处理RL插入方式,假设存在一棵树,如下,现插入“G”节点,假如不进行旋转的话,树结构为下图,遍历过程会检查哪里不平衡,检查到“C”节点和“H”节点的高度差大于1,而且插入节点“G”属于“E”节点的右子树的左子树,于是进行右左双旋,
先以“F”节点为轴进行右单旋,结果为,
再以“F”节点为轴进行左单旋,得到最终结果,
个人心得:这里的旋转保证的仍然是中序遍历的序列,每次旋转的都是同一个节点,旋转的都是那个深度为2的节点。
插入
插入时可能会遇到四种不同的插入方式,分别是:LL插入方式、RR插入方式、LR和RL插入方式。根据不同的插入方式对应做旋转操作即能使树达到平衡状态。
注意的一点是确定最底层首先出现不平衡的节点去判断其属于哪种方式进行调整。
查找
AVL树因为属于二叉搜索树,所以查找时与BST树完全一样
删除
删除操作主要分两种情况,一种是删除后不会影响平衡,那么直接按照BST树规则删除。
另外一种是删除后会影响树的平衡,那么则需要再做旋转处理。