数据结构跳表原理学习

前面学习很多类的源码过程中,底层基本都是数组和链表,今天学习第三种结构跳表(SkipList)。

跳表解决的问题

一个有序的数组如果我们要判断一个数据是否存在可以通过二分查找法非常快速的判断出来,但是如果是一个有序的链表结构,因为不知道链表两个节点之间的数量,就不能通过二分查找法实现了。

那么就只能通过从头开始遍历查询,但是这种查询是最慢的方式,那么就需要通过其他方法来实现了,而跳表就能够解决这个问题。

跳表出现过程

链表不能快速判断数据是否存在的原因在于不能使用像二分查找法这种算法,不能实现的原因是找不到中间节点,那么我们可以通过把中间节点记录下来,这样就能够找到了。

但是链表是在随时变化的,所以并不能记录中间节点,那么我们可以没间隔一个节点记录一下,把记录的节点组成一个新的链表,如下图:
数据结构跳表原理学习_第1张图片

通过间隔保存,新的链表数量少了接近一半,这样查询起来就要快很多了,比如要查询9,那么就可以从间隔提取那个链表开始查询,查询顺序是1—>5—>8—>8(下一层)—>9。

如果数据太长这样只经过一次抽取还是太大了,间隔链表的数据还是太长,效率还是太大,可以进行多次提取,最终结果如下图:

数据结构跳表原理学习_第2张图片

通过这种多次抽取,最上面的链表长度已经大大的减少,尤其在数据量很大的时候能够大幅提高执行效率。

跳表的查询

那么跳表的查询是如何实现的呢?这里以上图为例,判断12是否在链表中。

首先拿到最顶上的节点,如果当前节点大于12那么说明12不存在链表中,然后当前节点的右节点与12比较,发现比12大,那么节点下沉。

下层到第二层验证右节点(第二层值为8的节点)发现比12小,切换验证值为8这个节点,然后再验证节点的右节点(第二次值为13的节点)发现比12大,所以再次下沉。

来到第三层值为8的节点,发现它的右节点11比12小,所以切换到11节点进行验证右节点,11节点的右节点为13,比12大,所以再次下沉;

来到第四层值为11的节点,发现它的右节点等于12,所以存在。如果发现小于12那么需要继续往右走,发现大于12则往下走,如果下节点为null则查找结束,说明不存在。

验证的过程如下图:

数据结构跳表原理学习_第3张图片

判断的流程总的来说比较简单,拿到最顶层最左边的节点,如果当前节点比判断的值大则直接不存在,接下来就是当前节点的右节点与值得比较,根据判断结果分三种情况:

相等说明存在,也就是找到了;

右节点较大,往下沉,如果下层为null,则说明到了最底层,所以不存在;

右节点较小,切换右节点继续验证,右节点的节点为null则下沉,下沉为null则说明不存在;

总结

今天只是简单的梳理了跳表的原理,但是也可以看出来跳表是一个最典型的空间换时间解决方案,而且只有在数据量较大的情况下才能体现出来优势。而且应该是读多些少的情况下才能使用,所以它的适用范围应该还是比较有限的。

Java程序员日常学习笔记,如理解有误欢迎各位交流讨论!

数据结构跳表原理学习_第4张图片

你可能感兴趣的:(链表)