平衡二叉树
搜索树的结点按不同插入次序,将导致不同的深度和平均查找长度ASL。
- 引例:
【简单解析】例如图一: 寻找Jan结点的查找长度为1,Feb的查找长度为2,Mar的查找长度为2,Apr,June,May的查找长度为3……
因此 ASL(图a)=【1x(第一层总节点数)+2x(第二层总节点数)+3x(第3层总节点数)+.......】/ 总结点数
不难发现,上述三个图中图b的平均查找长度ASL最小,所以这样的结构查找效率很好,它具有的特点是左右两边相对平衡。
------------------那么什么是平衡二叉树?怎样判断一棵树是否是平衡二叉树呢?----------------
(先抛出一个概念:)
-
平衡因子(Balance Factor,简称BF):
-------- BF(Tree)= hL - hR (hL,hR分别表示左、右子树的高度) ---------
-
平衡二叉树(AVL树):
是一棵空树或 任意结点左、右子树高度差的绝对值不超过1,即 | BF(Tree)|<=1
【注】 若给定N个结点的平衡二叉树,它的最大高度为O( N).
-
平衡二叉树的调整:
One: LL左单旋
当插入 Aug 和 Apr 时,Mar的平衡因子变为 2 >1,所以Mar是失衡的“发现者”,而Apr是失衡的“麻烦结点”。
而此时“麻烦结点”是位于“发现者”的左子树的左子树。
因此我们进行LL旋转(左单旋)【注意旋转时仍然要保持是搜索树,左边小右边大】
针对Apr,Aug,Mar三个结点进行LL单旋时,Apr<Aug<Mar因此旋转后Aug为根,Apr为左子树,Mar为右子树。

对于上图:在BL左或右子树插入新节点时,A为发现者,新节点为破坏者,新节点是插在A的左子树的左子树 BL上,所以针对A、B、BL 进行左左单旋 ,而BL<B<A,所以B作为根,BL作为左子树,A作为右子树,而A>【BR】>B, 所以BR放在A的左子树上。OK啦~
Two: RR单旋
当插入 May 和 Nov 时,Mar的平衡因子变为 | -2 |>1, 所以Mar是失衡的“发现者”,而Nov是失衡的“麻烦结点”。
而此时“麻烦结点”是位于“发现者”的 右子树的右子树 。
因此我们进行RR旋转(右单旋)【注意旋转时仍然要保持是搜索树,左边小右边大】
针对May,Nov ,Mar三个结点进行LL单旋时,Mar < May < Nov 因此旋转后 May 为根,Mar 为左子树,Nov 为右子树。

对于上图:在BR左或右子树插入新节点时,A为发现者(|-2|>1),新节点为破坏者,新节点是插在A的右子树的右子树 BL上,所以针对A、B、BR 进行右右单旋 ,而 A < B < BR,所以B作为根,BR作为右子树,A作为左子树,而B>【BL】>A,所以BL放在A的右子树上就OK啦~
Three: LR双旋
当插入Jan时,May的平衡因子变为 |2 |>1, 所以May是失衡的“发现者”,而Jan是失衡的“麻烦结点”。
而此时“麻烦结点”是位于“发现者”的 左子树的右子树 。
因此我们进行LR旋转(左右双旋时, Aug<Mar< May 因此旋转后 Mar 为根,Aug 为左子树,May 为右子树。

对于下图:在CL或CR的左或右子树插入新节点时,A为发现者(|2|>1),新节点为破坏者,新节点是插在A的左子树的右子树 CL或CR上,所以针对A、B、C 进行左右双旋 ,而 B< C < A,所以C作为根,A作为右子树,B作为左子树,而B<【CL】<C,C<【CR】<A 所以CL放在B的右子树上,CR放在A的左子树 就OK啦~
Four: RL双旋
当插入Feb时,Aug的平衡因子变为 |-2 |>1, 所以Aug是失衡的“发现者”,而Feb是失衡的“麻烦结点”。
而此时“麻烦结点”是位于“发现者”的 右子树的左子树 。
因此我们进行RL旋转(右左双旋时, Aug<Dec<Jan 因此旋转后 Dec 为根,Aug 为左子树,Jan为右子树。
【注】Apr>Aug,挂在Aug的左子树上。Jan>Feb>Dec,所以Feb挂在Jan的左子树上,而July>Jan,还挂在右子树上。

对于下图:在CL或CR的左或右子树插入新节点时,A为发现者(|2|>1),新节点为破坏者,新节点是插在A的右子树的左子树 CL或CR上,所以针对A、B、C 进行左右双旋 ,而 A< C <B,所以C作为根,A作为左子树,B作为右子树,而A<【CL】<C,A<【CR】<B所以CL放在A的右子树上,CR放在B的左子树 就OK啦~
-
Such as
-----------------------------一:插入June-----------------------------
- 插入June后,Mar失衡,而June是在Mar的左子树的右子树上,所以对Mar、Dec、Jan进行LR双旋。
- Dec<Jan<Mar,所以以Jan为根结点,Dec为左子树,Mar为右子树。
- Dec<Feb<Jan,所以Feb挂在Jan的左子树上,Dec的右子树上。
- July>Jan应挂在Jan的右子树上,但July又<Mar所以最终挂在Mar的左子树,June跟着过去了。

------------------------二:插入Oct----------------------
- May为发现者,Oct是在May的右子树的右子树插入的,所以May、Nov、Oct进行RR单旋即可。
- May<Nov<Oct,所以Nov为根节点,May为左子树,Oct为右子树即可。

-------------------------三:插入Spet---------------------
Sept插入后仍然平衡,结构无需调整,但要及时修改平衡因子。~

【注】我们发现不是Spet插入后不用做调整但是各节点平衡因子仍要改变。
-
正经致谢: