(转)跳跃表skiplist-原理及Java实现
在数据结构中,集合的最基本的体现方式无外乎两种,一种是内存结构连在一起的数组的结构,一种是内存分散的通过指针连接的链表结构。形式上,有两种存放方式,一种是排序的,一种是非排序的。排序的重要主要是为了检索快速使用的。如果对于集合中的元素很少,几个到100个,排序和非排序两种方式是没有区别的,全遍历也不会消耗多长时间。可是当集合中的个数特别多的时候,排序这个时候就相当的重要。
回归主题,跳表是一种随机化的数据结构,目前开源软件 Redis 和 LevelDB 都有用到它。
我们看名字,跳表这个词可能有点是链表结构,是的没错,就是全部的链表结构,而且是有序的链表结构。但是我们知道,即使对于排过序的链表,我们对于查找还是需要进行通过链表的指针进行遍历的,时间复杂度很高依然是O(n),这个显然是不能接受的。是否可以像数组那样,通过二分法进行查找呢,但是由于在内存中的存储的不确定性,不能这做。
但是我们可以使用二分法的思想,在链表结构中选择瞄点,这个瞄点和原始点使用指针连接,查找的时候,先查瞄点,找到合适的瞄点后,通过指针映射到原始数据节点,再往后查找,思想和二分法查找一模一样。通过描述可能还不能完全理解,可以看下面的图:
跳表的结构模型
我们简单分析一下上面的图,如果这个链表已经创建好了,比如查找字母g,现先在第三层进行查找,因为e<g<h,所以这里我们找到了第三层的e节点,e节点链接到下一层的e节点,再进行向后查找,发现f<g<h,于是定位到f节点并从f节点向下找到第一层的f节点,f节点向后,找到了数据的g节点。整个查找流程结束。
跳表的每一层保证得有第一个元素和最后一个元素。另外层数也不能过多。
但是有人疑问了,既然性能直抵二分法,为什么不直接用数组的方式呢。是二分法的确简单,但是我们需要注意的是,不能光看查找,还得看插入、删除等写入的操作,我们知道,数组的方式插入和删除需要重新分配大的整块资源,而且需要进行内存拷贝,移动数组,性能就比较低下了。链表的方式对于处理元素的插入具有非常明显的优势,大家再对照上面的图看看我们跳表如何实现元素的插入。需要注意的是元素的插入的时候,需要考虑新元素是否需要生成新一层的点,这就根据算法看看了。
附具体实现算法:跳表原理及JAVA实现
阅读更多- 【算法导论33】跳跃表(Skip list)原理与java实现
- 【算法导论33】跳跃表(Skip list)原理与java实现
- 跳跃表Skip List的原理和实现(Java)
- 浅析SkipList跳跃表原理及代码实现
- 每日一省之 ———— 一个简单的跳跃表(Skip List)的Java实现
- 【转】浅析SkipList跳跃表原理及代码实现
- 算法: skiplist 跳跃表代码实现和原理
- Skip List(跳跃表)原理详解与实现
- 浅析SkipList跳跃表原理及代码实现
- SkipList跳跃表(Java实现)
- Skip List(跳跃表)原理详解与实现
- 跳跃表(Skip List)-实现(Java)
- Skip List(跳跃表)原理详解与实现
- Java实现跳跃表(skiplist)的简单实例
- 跳跃表SkipList原理代码实现
- Skip List(跳跃表)原理详解与实现
- Skip List(跳跃表)原理详解与实现【转】
- Skip List(跳跃表)原理详解与实现
- Java基础 常见List实现原理 - ArrayList
- JAVA SkipList 跳表 的原理和使用例子