我看小码哥关于 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))