什么是跳跃表
引子
能够完成动态数据的增删改查最简便的数据结构是什么?
是链表。
链表查询的时间复杂度是O(n)。如何修改最简单的链表,能够让它查得快一点呢?
我们可以多增加一些连接,让它形成网络的结构。
你也可以把它改成一棵树,当然这也可以说是另一种数据结构了。
我们今天要讲跳跃表,skip list。
再增加一张链表,情况会变得很不同。
地铁的例子
某城市的地铁有两条线,一条慢线,它包含所有的车站;一条快线,它的车站是慢线的一个真子集。
数字表示街道号。
慢线位于第二层(最底层),快线在第一层。
比如你要去121街道。
最好的选择是先走快线,走开100街道,然后走慢线,到121街道。
这个就是跳跃表。
跳跃表的第一条规则就是:最底层(在这里我们用L2表示)要包含所有的节点。
那么问题来了:L1(上一层)应该设置几个呢?
L1的理想数值
L1的合理设计是:均匀分布。
既然L1均匀分布,那么查询一个节点的时间就是:
表示的长度或者说节点数量。
假设最初的节点数量是。也就是说,要使得尽量的小,要取什么值呢?
当且仅当时取到最小值。
所以完美的跳跃表应该是这个样子的:
让跳跃表更快
如何让跳跃表查得更快?
设计更多的层。
以上的结果是推测的,当然也可以证明。
现在的关键问题是等于几,使得查询时间最小?
或者说,在已知最底层的数量的情况下(),跳跃表应该设计几层?
所以查询的时间复杂度是。
重新设计地铁线
按照上面的推理,我们重新设计地铁线。
因为,所以我们设计三层。
那么层与层之间的比率是多少呢?假设第一层的节点数是是,于是,因此第一层有两个节点。第二层我们设置4个节点。