跳跃表简介
Skip lists are data structures that use probabilistic balancing rather than strictly enforced balancing. As a result, the algorithms for insertion and deletion in skip lists are much simpler and significantly faster than equivalent algorithms for balanced trees.
跳跃表使用概率均衡技术而不是使用强制性均衡,因此,对于插入和删除结点比传统上的平衡树算法更为简洁高效。
查找操作
利用链表,我们如何才能创造出一个查找效率高的数据结构呢?
1.有序的一条链表
遗憾的是,链表并没有随机访问的能力,因此我们无法利用二分查找算法,只能依次遍历整个链表,算法的时间为O(n)。
2.改进的思想
如果某些结点能够直接跳跃到另一个结点,将大大减少查找的次数,改善运行时间。
3.两层链表
如果使用两条链表,类似于纽约大都市的地铁,有“快线”和“慢线”之分,“快线”经过更少的站点(设为m个),可以减少中途停站的时间,而“慢线”经过所有的站点(设为n个),以保证人们的出行。坐地铁时,我们先坐“快线”到达离目的地较近的站点,再换乘“慢线”到达目的地站点。
出行时间为O(m+n/m),当m取√n时,时间最短,为O(√n)。
4.k层链表
在两条链表的基础上,如果采用更多的链表,会不会使得效率进一步提升呢?可以证明,使用k条链表时的最优时间复杂度为O(k*n^(1/k))。当k取lgn时为最优解,此时每两层链表的元素个数比为2,共有lgn层链表。
查找的时间复杂度为O(lgn),空间复杂度为O(n)。
插入操作
如何保证链表的层数和每层的元素个数,成为了维持跳跃表查找性能的核心。采用随机化的插入策略,可以保证每次插入的时间复杂度为O(lgn)。
将元素插入底层链表,然后运用“抛硬币算法”,若出现正面,则将该元素“提升”至上一层,直到出现反面。
由于两层链表的元素个数比为2,而提升的概率为1/2,因此在主观上此方法是很合理的。而经过严谨的论证,可以证明对于任意的α,有1-1/n^α的概率,插入操作的时间复杂度为O(lgn)。
删除操作
很简单,只需要逐层删除元素即可。
总结
跳跃表是比较高效的动态查找表数据结构。由于它的代码以及原理实现的简单性,更为人们所接受。
参考资料
MIT算法导论公开课:跳跃表