块状链表的长度(GPT 重制版)
2026-09-08
本文完全由 GPT 5.6 sol 直接生成,改进了原博客 块状链表的长度 的证明,并给出了更强的结论。
0. 引入
块状链表就是一个链表,每个节点指向一个空间大小为
给定参数
接下来考虑如下维护策略:
- 数组未满时直接插入;
- 数组已满时,把
个元素尽可能均分到两个节点; - 删除元素后,如果当前节点可以和左邻节点合并,则合并;否则尝试和右邻节点合并;
- 如果删除后节点为空,则直接删除。
我们希望控制
对于
并且这个界可以取到。
特别地,
其中常数
1. 最坏情况
先构造一个例子。
通过不断插入,可以得到
取奇数位置的节点,把它们不断删除到只剩一个元素:
删除过程中不会发生合并,因为这些节点旁边都有一个满块。
然后对所有大小为
记分裂出的两个块大小为
于是得到
假设一共有
而元素总数为
所以恰好有
这提示我们真正应该证明的是
事实上,更强的结论成立:这个不等式对链表的任意连续区间都成立。
2. 区间不变量
给大小为
对于链表上的一个连续区间
如果
于是
等价于
接下来证明:
定理:任何时刻,对于任意非空连续区间
2.1 两个简单事实
首先,一个满块的权值为
因此,如果一个区间中包含一个满块:
- 满块在区间内部时,左右两段各自最多亏损
,所以整个区间权值至少为 ; - 满块在区间端点时,只需承担一侧的亏损,所以整个区间权值至少为
。
其次,设两个相邻节点大小为
所以
这两个节点原来的总权值至少为
如果一个区间包含这两个节点,左右两段各自最多亏损
这个下界恰好足够支付一次删除造成的
3. 证明
对操作次数进行数学归纳。
初始链表为空时命题平凡成立。
假设操作前所有连续区间都满足
考虑最后一次操作。
case 1:不产生分裂的插入
一个节点大小从
它的权值增加
所以所有受影响区间的权值只会增加。
case 2:产生分裂的插入
一个满块
且
先考虑一个同时包含
把
而旧区间包含一个满块,所以旧区间权值至少为
因此新区间权值至少为
再考虑一个只包含
由于
设新区间包含的节点大小为
又因为
对于
所以新区间权值至少为
case 3:删除后不发生合并
如果新区间只包含被删除的节点,那么这个节点非空,所以大小至少为
否则,新区间至少还包含被删除节点的一侧邻居。
由于删除后没有发生合并,这两个相邻节点在删除前的大小之和至少为
由前面的结论,旧区间权值至少为
删除一个元素使权值下降
case 4:删除后发生合并
假设两个节点大小为
的节点。
操作前这两个节点总权值为
操作后为
两者之差为
也就是说,删除并合并以后,所有相关区间的权值反而增加了
case 5:删除后节点为空
大小为
删除这个节点以后,跨过这个位置的区间相当于去掉了一个权值为
命题保持。
证毕。
4. 结论
取整个链表作为区间,有
因此
而第 1 节构造出的状态满足
所以这个界可以取到。
因此固定
对应的最坏空间利用率趋于
当
所以不存在
恒成立。
如果用这个上界估计插入、删除复杂度,那么
把
渐近上仍然有
5. 一个推广
上面的证明实际上没有真正用到“尽可能均分”,只用到了分裂后较小的节点不能太小。
考虑更一般的策略:
- 满块分裂成
,要求
- 删除以后,只有当相邻两个节点大小之和不超过
时才合并,其中
令
用完全相同的证明,对任意连续区间中的
因此
原来的策略中
对于
所以
这里还能看出,“均分”其实比需要的条件更强。
只要每次分裂以后两个节点都至少有
个元素,就仍然可以得到完全相同的最坏情况上界。
例如
这样的分裂,也仍然有
所以从节点数量的最坏情况来看,
另一方面,无论怎么二分,一个满块溢出以后两个新节点总共都只有
这样的结构,每三个节点只有
所以如果只允许 split 和“能装下才 merge”,最坏利用率就无法突破约
要继续提高这个下界,需要在删除后允许从邻居借元素或重新分配元素,而不能只做 merge。