题目TC: 18.2-4
分析
因为插入B树的数字是递增的,所以只有最右边一条链的节点上可能有多于一个key。
我们先关注整个B树最右下角的节点,称之为A。
当插入到第3个数字时,A(这时候也是根)满了,然后在插入下一个数字4的时候,其分裂,变成
再插入4变成
注意到一个节点分裂之后(在把插入的数字塞到节点里之前),节点里还会剩下1个key。所以一个节点从上一次满到下一次满,需要插入两个数字。
即A在n=3,5,7,…的时候是满的。
n=5:
n=6:
n=7:
每个节点是在它满了之后,插入下一个数字时分裂的,即A在插入n=4,6,8,10,12,14,16…之后分裂。
接下来考虑A的父亲,称为B,它在n=4即A首次分裂之后出现。
A每分裂一次,相当于给B插入一个数字。即n=4时,给B插入第一个数字,n=6时,给B插入第二个数字…
所以在A分裂三次之后(n=8之后),B就(第一次)满了。
接下来每给B插入两个数字,即A每分裂两次,B又会变满一次。所以B是满的当n=8,12,16,20,24,…的时候。
同样地,B也是在它满了之后,插入下一个数字时分裂的,即B在插入n=9,13,17,21,25…之后分裂。
再考虑B的父亲C。
B分裂一次相当于给C插入一个数字。所以与上面类似,在n=17,25,33,…的时候C是满的,在n=18,26,34,…的时候C分裂。
…
以此类推。
对于每一个节点,它的右孩子分裂三次之后,在插入下一个数字的时候它第一次分裂。
之后它的右孩子每分裂两次,在插入下一个数字的时候它分裂一次。
用归纳法,得到第i个节点(第1个节点是A,第2个节点是B…)两次分裂的间隔是2i个数字。
再用Si表示第i个节点第一次分裂的时间,有
S1=4 Si=Si−1+2×2i−1+1
进而Si=2i+1+i−1
统计数量
如何统计插入n个数字后的节点数量Tn?
初始数量为T0=1,即空树有一个节点。
对于之前我们考虑的每一个节点,它第一次作为根分裂的时候,分裂一次节点数量加2(它自己一分为二,且加了另外一个根),之后它就是不是根了,分裂一次数量加1。
所以当Si≤n的时候,第i个节点对最终的数量有贡献,且贡献为1加上其分裂次数,我们知道第i个节点在插入Si,Si+2i,Si+2×2i,Si+3×2i,…时分裂,故分裂次数为其中小于等于n的数字的个数,等于
⌊2in−Si⌋+1
则贡献为
1+(⌊2in−Si⌋+1)=⌊2in−Si⌋+2=⌊2in−2i+1−i+1⌋+2=⌊2in−i+1⌋
所以总的节点数量是1加上各个i贡献之和,即
Tn=1+i=1∑∞[Si≤n](⌊2in−i+1⌋)=1+i=1∑2i+1+i−1≤n⌊2in−i+1⌋=1+i=0∑2i+2+i≤n⌊2i+1n−i⌋
一般问题
在解决这个问题的时候,我们并没有依赖minimum degree为2这个特性,所以我们可以用同样的方法解决minimum degree为任意t≥2的情形。
类似上面的方法,用归纳法,第i个节点分裂两次的间隔是ti个数字。
且第一个节点第一次分裂的时间为插入第2t个数字的时候,第i个节点第一次分裂是在第i−1个节点分裂2t−1次后插入下一个数字的时候,即
S1=2t Si=Si−1+(2t−2)ti−1+1
进而
Si=i−1+2t+j=1∑i−1(2t−2)tj=i+1+j=0∑i−1(2t−2)tj=i+1+(2t−2)j=0∑i−1tj=i+1+(2t−2)t−1ti−1=2ti+i−1
对于Si≤n的节点,其对答案的贡献为
⌊tin−Si⌋+2=⌊tin−2ti−i+1⌋+2=⌊tin−i+1⌋
所以总的节点数为
Tn=1+i=1∑∞[Si≤n](⌊tin−i+1⌋)=1+i=1∑2ti+i−1≤n⌊tin−i+1⌋