AVL树原理

224 阅读3分钟

我看小码哥关于 ALH树 的视频,有些疑惑,在网上查,却发现找不到比较戳中我痛点的原理文章,所以在后来自己明白过来之后,写成日志以作记录。并且我觉得他这个表示方式比网上的其他图好太多了。

左旋

图片中元素说明

  • 图中描述的情况是:添加节点后树失衡的情况
  • g, p, n 是节点,分别是 grand, parent, node 的缩写,其中 g 是树中最先失衡的节点
  • T0 等是指树,树的高度不定,甚至有可能是0
  • 在同一条虚线上的子树表示:祖先节点到这些子树的最低叶子节点的高度一样
  • 红色的色块是被新添加的子节点

疑问1:p 和 n 一定不为空吗?

一定不为空

新添加的子节点的父节点有两种可能:原来只有一个子节点,或者原来没有节点。

原来只有一个子节点:那新添加的子节点不会导致父节点的高度变化,所以也就不会引起祖父节点的失衡,整棵树也不会失衡。

原来没有节点:父节点的平衡因子由 0 变为 1,没有失衡,新添加的节点当然也不会失衡。

所以最先失衡的节点一定不是最下面的两个节点,所以 p 和 n 一定不会为空。

疑问2:各个子树的高度就如图片中高度一样吗?

是的。

节点 g 到 T0 和 到 T3 的长度差一定是 -1:

  • 假设 T0 和 T3 在同一条虚线上,那么 T3 增加节点时,就不会失衡
  • 假设 节点 g 到 T0 和 到 T3 的长度差一定是 1,那么 T3 增加节点时,也不会失衡 所以可以确定 T0 和 T3 的关系一定如图所示

T2 和 T3 一定一样长:

  • 假设 T2 比 T3 长 1,那么在没有添加新节点之前就已经失衡了
  • 假设 T2 比 T3 短 1,那么添加了新节点之后,p 就会首先失衡,那 g 就不是最先失衡的了

T1 和 T2, T3 一定在同一条虚线上:

  • 假设 T1 到达最下面一条虚线,那在添加新节点之前就已经失衡了
  • 假设 T1 达到最上面一条虚线,那么添加了新节点之后,p 就会首先失衡,那 g 就不是最先失衡的了

疑问3:旋转之后,不会导致更高的节点失衡吗?

只要旋转之后最高节点的高度跟原来一样,更高的节点就不会失衡。

原来最高的节点是 g,高度是 T3 + 3。

旋转之后最高的节点是 p,高度是 T3 + 2 + 1。

所以不会导致更高节点失衡。

分析可知,如果新添加的节点在最先失衡的节点的左子树的左子树上,那么各个节点以及树的情况一定如图所示。

注意:n 有可能就是新添加的节点,也有可能不是。

怎么达到平衡的

失衡的根本原因是:T3 的高度增高,导致它需要上移了。

根据二叉搜索树的规则,图中各子树中节点以及节点的大小排序如下:

T0 < g < T1 < p < T2 < n < T3

原来的树就可以表示成 (括号内就是一棵树):

(T0 < g < (T1 < p < (T2 < n < T3)))

由于 T3 要求上移,所以就变化为:

((T0 < g < T1) < p < (T2 < n < T3))

双旋也是一样的道理