跳跃表的推导和数学证明

引子

能够完成动态数据的增删改查最简便的数据结构是什么?

链表


链表查询的时间复杂度是O(n)。如何修改最简单的链表,能够让它查得快一点呢?


我们可以多增加一些连接,让它形成网络的结构。


你也可以把它改成一棵树,当然这也可以说是另一种数据结构了。

我们今天要讲跳跃表,skip list。

再增加一张链表,情况会变得很不同。


地铁的例子

某城市的地铁有两条线,一条慢线,它包含所有的车站;一条快线,它的车站是慢线的一个真子集。


数字表示街道号。

慢线位于第二层(最底层),快线在第一层。

比如你要去121街道。

最好的选择是先走快线,走开100街道,然后走慢线,到121街道。

这个就是跳跃表。

跳跃表的第一条规则就是:最底层(在这里我们用L2表示)要包含所有的节点。

那么问题来了:L1(上一层)应该设置几个呢?


L1的理想数值

L1的合理设计是:均匀分布。

既然L1均匀分布,那么查询一个节点的时间就是:
T = ∣ L 1 ∣ + ∣ L 2 ∣ ∣ L 1 ∣ T=|L_1|+\frac{|L_2|}{|L_1|} T=L1+L1L2

∣ L 1 ∣ |L_1| L1表示 L 1 L_1 L1的长度或者说节点数量。

假设最初的节点数量是 n n n。也就是说 ∣ L 2 ∣ = n |L_2|=n L2=n,要使得 T T T尽量的小, ∣ L 1 ∣ |L_1| L1要取什么值呢?

T = ∣ L 1 ∣ + n ∣ L 1 ∣ ≥ 2 n T=|L_1|+\frac{n}{|L_1|} \geq 2 \sqrt{n} T=L1+L1n2n

当且仅当 ∣ L 1 ∣ = n |L_1|=\sqrt{n} L1=n 时取到最小值。

所以完美的跳跃表应该是这个样子的:

让跳跃表更快

如何让跳跃表查得更快?

设计更多的层。


以上的结果是推测的,当然也可以证明。

现在的关键问题是 k k k等于几,使得查询时间最小?

或者说,在已知最底层的数量的情况下( n n n),跳跃表应该设计几层?

所以查询的时间复杂度是 O ( log ⁡ 2 n ) O(\log_2n) O(log2n)

重新设计地铁线

按照上面的推理,我们重新设计地铁线。

因为 n = 8 n=8 n=8,所以我们设计三层。

那么层与层之间的比率是多少呢?假设第一层的节点数是是 r r r,于是 r 3 = 8 r^3=8 r3=8,因此第一层有两个节点。第二层我们设置4个节点。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值