您的位置:首页 > 编程语言 > Java开发

(转)跳跃表skiplist-原理及Java实现

2018-07-26 14:10 134 查看

在数据结构中,集合的最基本的体现方式无外乎两种,一种是内存结构连在一起的数组的结构,一种是内存分散的通过指针连接的链表结构。形式上,有两种存放方式,一种是排序的,一种是非排序的。排序的重要主要是为了检索快速使用的。如果对于集合中的元素很少,几个到100个,排序和非排序两种方式是没有区别的,全遍历也不会消耗多长时间。可是当集合中的个数特别多的时候,排序这个时候就相当的重要。

回归主题,跳表是一种随机化的数据结构,目前开源软件 Redis 和 LevelDB 都有用到它。

我们看名字,跳表这个词可能有点是链表结构,是的没错,就是全部的链表结构,而且是有序的链表结构。但是我们知道,即使对于排过序的链表,我们对于查找还是需要进行通过链表的指针进行遍历的,时间复杂度很高依然是O(n),这个显然是不能接受的。是否可以像数组那样,通过二分法进行查找呢,但是由于在内存中的存储的不确定性,不能这做。
但是我们可以使用二分法的思想,在链表结构中选择瞄点,这个瞄点和原始点使用指针连接,查找的时候,先查瞄点,找到合适的瞄点后,通过指针映射到原始数据节点,再往后查找,思想和二分法查找一模一样。通过描述可能还不能完全理解,可以看下面的图:



跳表的结构模型 

我们简单分析一下上面的图,如果这个链表已经创建好了,比如查找字母g,现先在第三层进行查找,因为e<g<h,所以这里我们找到了第三层的e节点,e节点链接到下一层的e节点,再进行向后查找,发现f<g<h,于是定位到f节点并从f节点向下找到第一层的f节点,f节点向后,找到了数据的g节点。整个查找流程结束。

跳表的每一层保证得有第一个元素和最后一个元素。另外层数也不能过多。

但是有人疑问了,既然性能直抵二分法,为什么不直接用数组的方式呢。是二分法的确简单,但是我们需要注意的是,不能光看查找,还得看插入、删除等写入的操作,我们知道,数组的方式插入和删除需要重新分配大的整块资源,而且需要进行内存拷贝,移动数组,性能就比较低下了。链表的方式对于处理元素的插入具有非常明显的优势,大家再对照上面的图看看我们跳表如何实现元素的插入。需要注意的是元素的插入的时候,需要考虑新元素是否需要生成新一层的点,这就根据算法看看了。

附具体实现算法:跳表原理及JAVA实现

阅读更多
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: