拜托,面试别再问我跳表了!

何为跳表?

跳表是一个随机化的数据结构,实质就是一种能够进行二分查找的有序链表算法

跳表在原有的有序链表上面增长了多级索引,经过索引来实现快速查找。数组

跳表不只能提升搜索性能,同时也能够提升插入和删除操做的性能。缓存

跳表详解

有序链表

skiplist1

考虑一个有序链表,咱们要查找三、七、17这几个元素,咱们只能从头开始遍历链表,直到查找到元素为止。数据结构

上述这个链表是有序的,可是不能使用二分查找,是否是很捉急?(P.S.数组能够实现二分查找)性能

那么,有没有什么方法能够实现有序链表的二分查找呢?学习

答案是确定的,那就是咱们将要介绍的这种数据结构——跳表。指针

跳表的演进

咱们把一些节点从有序表中提取出来,缓存一级索引,就组成了下面这样的结构:code

skiplist2

如今,咱们要查找17这个元素是否是要快不少呢?排序

咱们只要从一级索引日后遍历便可,只须要通过一、六、1五、17这几个元素就能够找到17了。索引

那么,咱们要查找11这个元素呢?

咱们从一级索引的1开始,向右到6,再向右发现是15,它比11大,此路不通,从6往下走,再从下面的6往右走,到7,再到11。

一样地,一级索引也能够往上再提取一层,组成二级索引,以下:

skiplist3

这时候咱们再查找17这个元素呢?

只须要通过六、1五、17这几个元素就能够找到17了。

这基本上就是跳表的核心思想了,其实这也是一个“空间换时间”的算法,经过向上提取索引增长了查找的效率。

跳表的插入

上面讲的都是跳表的查询,那么,该如何向跳表中插入元素呢?

好比,咱们要向上面这个跳表添加一个元素8。

首先,咱们先根据投硬币的方式,决定8这个元素要占据的层数,没错就是扔硬币,是否是很好玩儿^^

好比,层数level=2。

而后,找到8这个元素在下面两层的前置节点。

接着,就是链表的插入元素操做了,比较简单。

最后,就像下面这样:

skiplist4

跳表的删除

查询、插入元素都讲了,下面咱们就来讲说怎么删除元素。

首先,找到各层中包含元素x的节点。

而后,使用标准的链表删除元素的方法删除便可。

好比,要删除17这个元素。

skiplist5

标准化的跳表

上面举的例子是彻底随机的跳表,那么,若是咱们每两个元素提取一个元素做为上一级的索引会怎么样呢?

skiplist6

这是否是很像平衡二叉树,如今这颗树元素比较少,可能不太明显,咱们来看个元素个数多的状况。

skiplist6

能够看到,上一级元素的个数是下一级的一半,这样每次减小一半,就很接近平衡二叉树了。

时间复杂度

咱们知道单链表查询的时间复杂度为O(n),而插入、删除操做须要先找到对应的位置,因此插入、删除的时间复杂度也是O(n)。

那么,跳表的时间复杂度是多少呢?

若是按照标准的跳表来看的话,每一级索引减小k/2个元素(k为其下面一级索引的个数),那么整个跳表的高度就是(log n)。

学习过平衡二叉树的同窗都知道,它的时间复杂度与树的高度成正比,即O(log n)。

因此,这里跳表的时间复杂度也是O(log n)。(这里不一步步推倒了,只要记住,查询时每次减小一半的元素的时间复杂度都是O(log n),好比二叉树的查找、二分法查找、归并排序、快速排序)

空间复杂度

咱们仍是以标准的跳表来分析,每两个元素向上提取一个元素,那么,最后额外须要的空间就是:

n/2 + (n/2)^2 + (n/2)^3 + ... + 8 + 4 + 2 = n - 2

因此,跳表的空间复杂度是O(n)。

总结

(1)跳表是能够实现二分查找的有序链表;

(2)每一个元素插入时随机生成它的level;

(3)最低层包含全部的元素;

(4)若是一个元素出如今level(x),那么它确定出如今x如下的level中;

(5)每一个索引节点包含两个指针,一个向下,一个向右;

(6)跳表查询、插入、删除的时间复杂度为O(log n),与平衡二叉树接近;

彩蛋

为何Redis选择使用跳表而不是红黑树来实现有序集合?

首先,咱们来分析下Redis的有序集合支持的操做:

1)插入元素

2)删除元素

3)查找元素

4)有序输出全部元素

5)查找区间内全部元素

其中,前4项红黑树均可以完成,且时间复杂度与跳表一致。

可是,最后一项,红黑树的效率就没有跳表高了。

在跳表中,要查找区间的元素,咱们只要定位到两个区间端点在最低层级的位置,而后按顺序遍历元素就能够了,很是高效。

而红黑树只能定位到端点后,再从首位置开始每次都要查找后继节点,相对来讲是比较耗时的。

此外,跳表实现起来很容易且易读,红黑树实现起来相对困难,因此Redis选择使用跳表来实现有序集合。


欢迎关注个人公众号“彤哥读源码”,查看更多源码系列文章, 与彤哥一块儿畅游源码的海洋。

qrcode

相关文章
相关标签/搜索