下面是跳跃表的基本原理,REDIS的实现大致相同

跳跃表的一个特点是,插入NODE是通过随机的方式来决定level的,比较奇特

下面是skipList的一个介绍,转载来的,源地址:http://kenby.iteye.com/blog/1187303,为防止源地址丢失,故拷贝一份放在这里,望作者原谅。

———————————————转载开始—————————————————

为什么选择跳表

目前经常使用的平衡数据结构有:B树,红黑树,AVL树,Splay Tree, Treep等。

想象一下,给你一张草稿纸,一只笔,一个编辑器,你能立即实现一颗红黑树,或者AVL树

出来吗? 很难吧,这需要时间,要考虑很多细节,要参考一堆算法与数据结构之类的树,

还要参考网上的代码,相当麻烦。

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

它的效率和红黑树以及 AVL 树不相上下,但跳表的原理相当简单,只要你能熟练操作链表,

就能轻松实现一个 SkipList。

有序表的搜索

考虑一个有序表:

从该有序表中搜索元素 < 23, 43, 59 > ,需要比较的次数分别为 < 2, 4, 6 >,总共比较的次数

为 2 + 4 + 6 = 12 次。有没有优化的算法吗?  链表是有序的,但不能使用二分查找。类似二叉

搜索树,我们把一些节点提取出来,作为索引。得到如下结构:

这里我们把 < 14, 34, 50, 72 > 提取出来作为一级索引,这样搜索的时候就可以减少比较次数了。

我们还可以再从一级索引提取一些元素出来,作为二级索引,变成如下结构:

这里元素不多,体现不出优势,如果元素足够多,这种索引结构就能体现出优势来了。

跳表

下面的结构是就是跳表:

其中 -1 表示 INT_MIN, 链表的最小值,1 表示 INT_MAX,链表的最大值。

跳表具有如下性质:

(1) 由很多层结构组成

(2) 每一层都是一个有序的链表

(3) 最底层(Level 1)的链表包含所有元素

(4) 如果一个元素出现在 Level i 的链表中,则它在 Level i 之下的链表也都会出现。

(5) 每个节点包含两个指针,一个指向同一链表中的下一个元素,一个指向下面一层的元素。

跳表的搜索

例子:查找元素 117

(1) 比较 21, 比 21 大,往后面找

(2) 比较 37,   比 37大,比链表最大值小,从 37 的下面一层开始找

(3) 比较 71,  比 71 大,比链表最大值小,从 71 的下面一层开始找

(4) 比较 85, 比 85 大,从后面找

(5) 比较 117, 等于 117, 找到了节点。

具体的搜索算法如下:

  1. /* 如果存在 x, 返回 x 所在的节点,
  2. * 否则返回 x 的后继节点 */
  3. find(x)
  4. {
  5. p = top;
  6. while (1) {
  7. while (p->next->key < x)
  8. p = p->next;
  9. if (p->down == NULL)
  10. return p->next;
  11. p = p->down;
  12. }
  13. }

跳表的插入

先确定该元素要占据的层数 K(采用丢硬币的方式,这完全是随机的)

然后在 Level 1 ... Level K 各个层的链表都插入元素。

例子:插入 119, K = 2

如果 K 大于链表的层数,则要添加新的层。

例子:插入 119, K = 4

丢硬币决定 K

插入元素的时候,元素所占有的层数完全是随机的,通过一下随机算法产生:

  1. int random_level()
  2. {
  3. K = 1;
  4. while (random(0,1))
  5. K++;
  6. return K;
  7. }

相当与做一次丢硬币的实验,如果遇到正面,继续丢,遇到反面,则停止,

用实验中丢硬币的次数 K 作为元素占有的层数。显然随机变量 K 满足参数为 p = 1/2 的几何分布,

K 的期望值 E[K] = 1/p = 2. 就是说,各个元素的层数,期望值是 2 层。

跳表的高度。

n 个元素的跳表,每个元素插入的时候都要做一次实验,用来决定元素占据的层数 K,

跳表的高度等于这 n 次实验中产生的最大 K,待续。。。

跳表的空间复杂度分析

根据上面的分析,每个元素的期望高度为 2, 一个大小为 n 的跳表,其节点数目的

期望值是 2n。

跳表的删除

在各个层中找到包含 x 的节点,使用标准的 delete from list 方法删除该节点。

例子:删除 71

————————————————————转载结束—————————————————————

随机的层高level-相关资料

http://blog.csdn.net/kisimple/article/details/38706729

http://blog.csdn.net/unix21/article/details/10197115

[REDIS 读书笔记]第一部分 数据结构与对象 跳跃表的更多相关文章

  1. [redis读书笔记] 第一部分 数据结构与对象 简单动态字符串

    本读书笔记主要来自于<<redis设计与实现>> -- 黄键宏(huangz) redis主要设计了字符串,链表,字典,跳跃表,整数集合,压缩列表来做为基本的数据结构,实现键值 ...

  2. [redis读书笔记] 第一部分 数据结构与对象 对象类型

    - 从前面redis的基本数据结构来看,可以看出,redis都是在基本结构(string)的基础上,封装了一层统计的结构(SDS),这样让对基本结构的访问能够更快更准确,提高可控制度. - redis ...

  3. [redis读书笔记] 第一部分 数据结构与对象 对象特性

    一 类型检查和多态    类型检查,即有的命令是只针对特定类型的,如果类型不对,就会报错,此处的类型,是指的键类型,即robj.type.下面为有类型检查的命令: 对于某一种类型,redis下底层的实 ...

  4. [redis读书笔记] 第一部分 数据结构与对象 字典

    三 字典 字典是Hash对象的底层实现,比如用HSET创建一个HASH的对象,底层可能就是用一个字典实现的键值对. 字典的实现主要设计下面三个结构: /* * 哈希表节点 */ typedef str ...

  5. [redis读书笔记] 第一部分 数据结构与对象 整数集合

    typedef struct intset { // 编码方式 uint32_t encoding; // 集合包含的元素数量 uint32_t length; // 保存元素的数组 int8_t c ...

  6. [redis读书笔记] 第一部分 数据结构与对象 压缩列表

    压缩列表是为了节省内存而设计的,是列表键和哈希键的底层实现之一. 压缩列表的逻辑如下,

  7. [redis读书笔记] 第一部分 数据结构与对象 链表

    二 链表 1.链表节点使用ListNode结构,是一个双向的链表,同时,还实现了一个控制所有ListNode的结构list: typedef struct listNode { // 前置节点 str ...

  8. Redis学习笔记一:数据结构与对象

    1. String(SDS) Redis使用自定义的一种字符串结构SDS来作为字符串的表示. 127.0.0.1:6379> set name liushijie OK 在如上操作中,name( ...

  9. 《javascript权威指南》读书笔记——第一篇

    <javascript权威指南>读书笔记——第一篇 金刚 javascript js javascript权威指南 由于最近想系统学习下javascript,所以开始在kindle上看这本 ...

随机推荐

  1. [论文翻译]Practical Diversified Recommendations on YouTube with Determinantal Point Processes

    目录 ABSTRACT(摘要) 1 INTRODUCTION(简介) 2 RELATED WORK 2.1 Diversification to Facilitate Exploration(对应多样 ...

  2. 【DPDK】【ring】从DPDK的ring来看无锁队列的实现

    [前言] 队列是众多数据结构中最常见的一种之一.曾经有人和我说过这么一句话,叫做“程序等于数据结构+算法”.因此在设计模块.写代码时,队列常常作为一个很常见的结构出现在模块设计中.DPDK不仅是一个加 ...

  3. DP-01背包 (题)

    nyoj 325   http://acm.nyist.net/JudgeOnline/problem.php?pid=325 zb的生日 时间限制:3000 ms  |  内存限制:65535 KB ...

  4. 区间dp - 不连续的回文串

    Long long ago, there lived two rabbits Tom and Jerry in the forest. On a sunny afternoon, they plann ...

  5. VMware Workstation CentOS7 Linux 学习之路(3)--.net coreWeb部署

    1.首先创建一个文件夹,命名为core mkdir core cd core 2.我这里用FlashFXP连接Linux 把我发布的项目上传到CentOS7的core文件夹下 此时我输入命令 dotn ...

  6. mysql 查询中文数据

    select * from comm_user WHERE length(tags)!=CHAR_LENGTH(tags)

  7. Java.Json模板.省市区三级JSON

    [ { "name": "北京市", "city": [ { "name": "北京市", &quo ...

  8. 机器学习-决策树 Decision Tree

    咱们正式进入了机器学习的模型的部分,虽然现在最火的的机器学习方面的库是Tensorflow, 但是这里还是先简单介绍一下另一个数据处理方面很火的库叫做sklearn.其实咱们在前面已经介绍了一点点sk ...

  9. [题解][Codeforces]Codeforces Round #602 (Div. 1) 简要题解

    orz djq_cpp lgm A 题意 给定一个分别含有 \(\frac n2\) 个左括号和右括号的括号序列 每次可以将序列的一个区间翻转 求一个不超过 \(n\) 次的操作方案,使得操作完之后的 ...

  10. 《Sequence Models》课堂笔记

    Lesson 5 Sequence Models 这篇文章其实是 Coursera 上吴恩达老师的深度学习专业课程的第五门课程的课程笔记. 参考了其他人的笔记继续归纳的. 符号定义 假如我们想要建立一 ...