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

跳表

  跳表(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值
  

示意图:

  一个简单跳表的示意图如下:
  redis学习笔记(4)---跳表zskiplist_第1张图片

总结:

  1)跳表是有序集合的底层实现
  2)每个节点的level数都在1~32之间
  3)跳表中的所有节点按照score的值从小到大排列
  4)不同节点的score可以相同,但是每个节点的robj对象必须唯一



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

redis学习参考资料:
https://github.com/huangz1990/redis-3.0-annotated
Redis 设计与实现(第二版)

你可能感兴趣的:(redis学习笔记(4)---跳表zskiplist)