zskiplist是一个有序的集合,为了解决其他链表的插入、删除效率低、查询元素需要循环遍历等缺点,redis就采用了一个特殊的数据结构zskiplist(跳跃表)。
它在性能上跟红黑树差不多, 同时又比红黑树的实现简单。在插入、删除、查询等操作上的时间复杂度为o(logn)。

加入我们想查找 9 这个元素,步骤如下:

创建一个zskiplist的时间复杂度为O(1);
backward、forward、span等属性
释放一个节点的内存 时间复杂度O(1);
释放整个skiplist的内存 时间复杂度O(n);
从skiplist中删除并释放掉一个节点 时间复杂度O(logn),会涉及到3个步骤:
ele和score找到节点的位置(代码里变量x即为该节点,update记录每层x的上一个节点)zslDeleteNode把x节点从skiplist逻辑上删除根据范围删除节点 时间复杂度O(log(n)+m), m是范围内元素的个数;
优点:
优点:
在 redis/src/server.h 中
#define ZSKIPLIST_MAXLEVEL 32 /* Should be enough for 2^64 elements */
#define ZSKIPLIST_P 0.25 /* Skiplist P = 1/4 */
typedef struct zskiplist {
struct zskiplistNode *header, *tail; // 跳跃表头尾节点
unsigned long length; //节点个数
int level; //除头结点外最大的层数
} zskiplist;
typedef struct zskiplistNode {
sds ele; //存储字符串类型数据 redis3.0版本中使用robj类型表示,但是在redis4.0.1中直接使用sds类型表示
double score; //存储排序的分值
struct zskiplistNode *backward; //指向上一个节点,用于zrevrange命令
struct zskiplistLevel {
struct zskiplistNode *forward; //指向下一个节点
unsigned long span; //到达后一个节点的跨度(两个相邻节点span为1)
} level[]; //该节点在各层的信息,柔性数组成员
} zskiplistNode;