目录

 

1.skiplist简介

2.skiplist核心思想

3.skiplist原理

 3.1 跳表的查找

3.2 跳表的插入

3.3 跳表的删除

4.skiplist简单实现


1.skiplist简介

Skiplist是一个用于有序元素序列快速搜索的数据结构,由美国计算机科学家William Pugh发明于1989年。他在论文《Skip lists: a probabilistic alternative to balanced trees》中详细介绍了跳表的数据结构和插入删除等操作。论文是这么介绍跳表的:

  • Skip lists are a data structure that can be used in place of balanced trees.
  • Skip lists use probabilistic balancing rather than strictly enforced balancing and as a result the algorithms for insertion and deletion in skip lists are much simpler and significantly faster than equivalent algorithms for balanced trees.

也就是说,Skip list是一个“概率型”的数据结构,可以在很多应用场景中替代平衡树。Skip list算法与平衡树相比,有相似的渐进期望时间边界,但是它更简单,更快,使用更少的空间。 参考算法导论,跳表插入、删除、查找的复杂度均为O(logN)。

选择跳表的原因:

  • 目前经常使用的平衡数据结构有:B树,红黑树,AVL树,Splay Tree, Treep等,但是实现细节过于复杂。
  • 相比之下,跳表的原理相当简单,只要你能熟练操作链表,就能轻松实现一个 SkipList。目前开源软件 Redis 和 LevelDB 都有用到它。

2.skiplist核心思想

先从链表开始,如果是一个单链表,那么我们知道在链表中查找一个元素I的话,需要将整个链表遍历一次,时间复杂度为O(n)。

数据结构学习——skiplist跳表

如果是说链表是排序的,并且结点中还存储了指向后面第二个结点的指针的话,那么在查找一个结点时,仅仅需要遍历N/2个结点即可。因此查找的时间复杂度为O(n/2)。

数据结构学习——skiplist跳表

其实,上面基本上就是跳跃表的思想,每一个结点不单单只包含指向下一个结点的指针,可能包含很多个指向后续结点的指针,这样就可以跳过一些不必要的结点,从而加快查找、删除等操作。对于一个链表内每一个结点包含多少个指向后续元素的指针,这个过程是通过一个随机函数生成器得到,这样子就构成了一个跳跃表。这就是为什么论文“Skip Lists : A Probabilistic Alternative to Balanced Trees ”中有“概率”的原因了,就是通过随机生成一个结点中指向后续结点的指针数目。随机生成的跳跃表可能如下图所示。

数据结构学习——skiplist跳表

如果一个结点存在k个指向后续元素指针的话,那么称该结点是一个k层结点。一个跳表的层MaxLevel义为跳表中所有结点中最大的层数。跳表的所有操作均从上向下逐层进行,越上层一次next操作的跨度越大。

3.skiplist原理

skiplist的结构定义如下:

  1. 由多层结构组成;
  2. 每一层都是一个有序的链表;
  3. 最底层(Level 1)的链表包含所有元素;
  4. 如果一个元素出现在 Level i 的链表中,则它在 Level i 之下的链表也都会出现;
  5. 每个节点包含两个指针,一个指向同一链表中的下一个元素,一个指向下面一层的元素。

为了便于描述,将跳表结构绘画成如下形式。

数据结构学习——skiplist跳表

 3.1 跳表的查找

数据结构学习——skiplist跳表

例子:查找元素 117,会经历如下几个步骤:

  1.  比较 21, 比 21 大,往后面找
  2.  比较 37,   比 37大,比链表最大值小,从 37 的下面一层开始找
  3.  比较 71,  比 71 大,比链表最大值小,从 71 的下面一层开始找
  4.  比较 85, 比 85 大,从后面找
  5.  比较 117, 等于 117, 找到了节点。

3.2 跳表的插入

1)K小于链表的层数

先确定该元素要占据的层数 K(采用丢硬币的方式,这完全是随机的),然后在 Level 1 ... Level K 各个层的链表都插入元素。
例子:插入 119, K = 2

数据结构学习——skiplist跳表

2)K大于链表的层数

如果 K 大于链表的层数,则要添加新的层。
例子:插入 119, K = 4

数据结构学习——skiplist跳表

插入元素的时候,元素所占有的层数完全是随机的,通过某种随机算法产生。

3.3 跳表的删除

在各个层中找到包含 x 的节点,使用标准的 delete from list 方法删除该节点。

例子:删除 71

数据结构学习——skiplist跳表

4.skiplist简单实现

 

参考链接:https://blog.csdn.net/caoshangpa/article/details/78862339

相关文章:

  • 2022-01-13
  • 2021-11-28
  • 2021-04-25
  • 2021-10-07
  • 2022-12-23
  • 2021-10-18
  • 2022-01-19
猜你喜欢
  • 2021-06-07
  • 2021-12-29
  • 2021-11-29
  • 2021-08-21
  • 2021-06-30
  • 2021-05-28
  • 2021-07-12
相关资源
相似解决方案