博文:https://www.cnblogs.com/seniusen/p/9870398.html
应用场景:
1、hashmap只能点对点查找,数据库通过跳表机制实现范围查找,实现索引的拓展。
2、redis用跳表来实现有序集合的按区间查找数据,按区间查找数据,跳表key在 O(logn)时间复杂度定位区间的起点,然后在原始链表中顺序向后查询,非常高兴。红黑树效率没有跳表高。
链表:即使链表数据是有序的,如果想要查找某个数据,需要从头到尾,时间复杂度为O(n),效率低。
有序数组:如果要查找某个数据,可以通过二分法查找,时间复杂度为O(logn),但是数组需要连续的存储空间。
跳表:以空间换时间,类似于有序数组二分法查找+链表的实现。
对链表每两个节点提取一个节点至上级,并建立一个索引指向原始节点(二级跳表)
此时,我们要查找某个数据,会先在索引里面查找一个大的范围,然后再下降到原始链表进行精确查找
例如:查找数据16,发现数据16在13和17之间,这时,我们从13的地方下降到原始链表,并且往后继续查询。遍历节点数量有10个减少为7个。
因此,加了一层索引后,查找某一节点所需的遍历次数减少,提高了查找效率。
如下通过5级索引,来查找一个包含64个节点的例子。
在原始链表中,查找62需要遍历62次,通过5级节点,此时只需要11次就可以找到62节点。
因此:链表的长度越长,构建多级索引查找的效率提升越明显。
2、跳表查询分析
假设原始链表总共有n个节点,那么第一级索引有n/2个节点,第二级索引有n/4个节点,依次类推第k级索引有n/2^k 个节点。如果最高级索引有2个节点,那总索引级数k=log2n-1。加上原始链表,总共有log2n级。
在第k级索引中,假设查找的数据为x,当查找y节点时,发现y<x<z,此时我们从第y个节点下降到第k-1级索引继续查找。在第k-1级索引中,y节点和z节点间共有3个节点,因此 我们最多查找3个节点。因此,每一级索引最多遍历3个节点。
并总的级别数为log2n,因此查找的时间复杂度为3*log2n(O(logn))。由此,发现跳表的时间复杂度和二分法查找一样。
跳表所需的额外索引节点总数为n/2+n/4+n/8+…+4+2=n-2,所以跳表的空间复杂度为O(n),实际上,在实际开发中,原始链表中存储的数据对象可能很大,而索引节点只需存储关键值和几个指针,其额外占用的空间可以被忽略掉。