(a3)伸展树:算法实现
看清 splay 旋转细节与边界,掌握均摊 O(log n) 的记账分析
按 空格/→ 演示下一步
全部页面点击任意一页,跳回舞台从这页播放
(a3)伸展树:算法实现
看清 splay 旋转细节与边界,掌握均摊 O(log n) 的记账分析
功能接口
BST 你会用——Search、Insert、Delete。伸展树对外暴露的接口和它一模一样,签名都不变。区别藏在每次写操作之后多走的那一步。
押注时间局部性——高频节点天然浮到浅层
伸展算法
上一节看到了 splay 的接口:传入一个节点,它会被搬到树根。但「怎么搬」才是伸展树最巧妙的部分——每一步旋转的招式,取决于被搬节点在树中的位置。
刚用过的资料挪到桌面最顺手处;下次再拿它直接就到
四种情况
上一节要把 x 一路推到根。每一步看 x、父亲 p、祖父 g 三层关系,可归为四种对称情况;若 p 已是根节点则只做一次单旋收尾。
三层同向是一字型直梯(先动远的祖父),异向是之字型拐角(先动近的父亲)
查找算法
前页拆解了四种旋转情况,现在把它们串成完整流程——查找路线和普通 BST 没有差别,真正的差别在「找到之后」还要做一步。
不是为了这一次省事,而是让后面很多次拿取都快起来
插入算法
上页讲到查找算法——找到就把节点旋到根。那如果 key 不存在呢?这就到了插入登场的时候。
按分类号归位(BST 插入),再把复本放前台(splay 到根),方便借阅
删除算法
插入时我们靠「先查找再伸展」把节点带到根,删除同样能享受这个便利——目标节点一旦被抬到根,后续就只剩拼接两棵子树,无需讨论左右孩子是否齐备。
把要抽的卡片翻到最前(伸展到根),左右分两摞,再把右摞塞到左摞最大卡片后面
综合评价
前几页把伸展、查找、插入、删除都拆开了。现在把它们装回去看整体——伸展树到底是一种什么样的数据结构?
单次搬书费力,但下次拿就快了——和单次 O(n)、均摊 O(log n) 一个道理
本节要点
- ✓「访问即旋转」:把刚用过的节点提到根,形成热点加速
- ✓摊还 O(log n) 由四种情况共同保证,缺一即退化为 O(n)
- ✓增删查遵循同一套路:先伸展、再操作、再伸展
- ✓摊还 ≠ 最坏:刻意构造序列仍可让单次走到 O(n)
- ✓无平衡字段:靠旋转自维护,调试需打印路径观察树形
课后思考
先独立思考,再对照参考答案。三个问题层层递进:从机制到应用,再到理论边界。
参考答案zig 是父为根的最后一步;zig-zig/zig-zag 分别处理祖父-父-子同向与反向路径。势能分析证明:被访问节点在 splay 中势能下降,抵消路径代价,均摊 O(log n)。
参考答案热点被反复伸展到根,局部性极佳;但单次最坏 O(n)、均摊常数大于严格平衡树——延迟敏感、完全随机的访问模式不适合。
参考答案经典伸展树做不到。已有「严格伸展树」等变体可实现最坏 O(log n),但常数显著增大、实现更复杂,仅在可预知访问模式时值得。