您的位置:首页 > 数据库 > Redis

redis学习笔记(4)---跳表zskiplist

2016-05-04 19:05 375 查看

跳表

  跳表(skiplist)是一种有序的数据结构,它通过在每个节点中维护多个指向其它节点的指针,来达到快速访问的目的。

  跳表查找的时间复杂度平均为O(lgn),最坏情况下退化为单链表的O(n)。在大部分情况下,跳表的效率可以和平衡树相媲美,但是由于跳表的实现更加简单,因此很多地方用跳表来代替平衡树。redis使用跳表作为有序集合键的底层实现。

  跳表的定义在redis.h中

  

节点定义:

typedef struct zskiplistNode {
robj *obj;
double score;
struct zskiplistNode *backward;
struct zskiplistLevel {
struct zskiplistNode *forward;
unsigned int span;
} level[];
} zskiplistNode;


obj:存储的成员对象

score:分值,所有节点按照score从小到大按序排列

backward:后退指针

level:数组,其中的每一个元素包含了指向其它节点的指针和跨度信息

  每次创建一个跳表节点时,都会随机生成一个[1,32]之间的值作为level数组的大小。

  节点中的backward按照节点顺序依次指向前一个节点。

  然后通过level数组中的forward指针指向下一个节点,同时forward指针连接的两个节点之间的层次具有一 一对应关系。

跳表定义:

typedef struct zskiplist {
struct zskiplistNode *header, *tail;
unsigned long length;
int level;
} zskiplist;


  跳表保存了链表的头节点和尾部节点,

  length为跳表中的节点个数

  level为当前链表中层次最大的节点的层次数,即所有节点的最大level值

  

示意图:

  一个简单跳表的示意图如下:

  


总结:

  1)跳表是有序集合的底层实现

  2)每个节点的level数都在1~32之间

  3)跳表中的所有节点按照score的值从小到大排列

  4)不同节点的score可以相同,但是每个节点的robj对象必须唯一

本文所引用的源码全部来自Redis3.0.7版本

redis学习参考资料:

https://github.com/huangz1990/redis-3.0-annotated

Redis 设计与实现(第二版)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: