(a2)伸展树:双层伸展
拆透 zig-zig 和 zig-zag 的旋转结构,搞懂均摊对数复杂度由来
按 空格/→ 演示下一步
全部页面点击任意一页,跳回舞台从这页播放
(a2)伸展树:双层伸展
拆透 zig-zig 和 zig-zag 的旋转结构,搞懂均摊对数复杂度由来
双层伸展
上节的单层旋转把 x 一层一层往上挪,深链访问的摊还代价退化到 O(n)。解法是一次看三层——祖父、父亲、x,让 x 一步跨两层,沿途兄弟子树一并压低。
要把里层翻到外,得先把外层折进来再折内层;反过来只翻薄薄一片,效率低
子孙异侧
上节说需要双层旋转的情况有两类。本节看第一类:X 和 P 在 G 的两侧,呈之字形——典型的 zig-zag。
爷爷左、爸爸右、你左——之字形;要推你上去,先在爸爸那转一次,再到爷爷那转一次
子孙同侧
上节我们看了子孙异侧的「两次反向旋转」。如果 X 和 P 站在祖辈的同一侧,调整手法就要反过来——连续两次同向旋转。
两次同向旋转相当于把同侧的两段折弯一次拉直
点睛之笔
前两页我们按子孙异侧、子孙同侧看完了双层旋转的两种形态,但为什么非要绕这两层、而不是把目标节点一层层旋上去?这一页回到动机,回答双层伸展为何是伸展树的灵魂。
同侧连续对折两次(zig-zig),异侧翻向再折(zig-zag),每次都让纸带长度近乎减半
折叠效果
上一节我们用两步旋转把节点连提两层——看似只比单旋快一点,但叠起来就有了质变:每次伸展后,根到目标节点的路径都会被「对折」一次。
毛巾折一次长度减半,再折再减半;伸展树也用同样方式把「走到目标」的距离压短
分摊性能
前页把查找路径折到根,局部结构已经变短;可这不等于每次访问都只有 O(log n)。把一整串访问合起来算,分摊上界才是理解性能的关键。
一次有人排很久,只是那一次慢;把整队总耗时均摊到每个人,才对应分摊上界
最后一步
前面讲过同侧、异侧的双层旋转,可当节点只剩一步就能抵达根时——情形变了。
双层操作是连跨两级,最后一级只需轻跨一步便登顶
本节要点
- ✓单旋只把访问节点往上挪一层,路径反而被拉细长
- ✓双层旋转的核心:爷孙关系要配对处理,跨层级协作
- ✓同侧连转同向、异侧一正一反——两种折叠姿态
- ✓折叠效果:访问路径被压向根部,节点深度大致折半
- ✓分摊 O(log n):连续 m 次操作均摊对数时间
课后思考
先合上笔记自己想想,再对照参考答案。
参考答案关键在折叠效果——祖父先转让路径深度对半折,后续旋转延续这一折叠;若先转父亲,深度只减 1,无法形成分摊保证。
参考答案按对数级折半递减:log₂n, log₂n−1, …, 直到稳定在 1。这就是折叠效果——两次伸展砍掉一半路径。
参考答案因为 zig 情况下 x 已到顶层,父亲就是根,没有祖父可以「转上去」。单次旋转直接把 x 提到根部——双层规则在此自然退化。