zset的两种实现方式
ziplist:满足以下两个条件的时候
- 元素数量少于128的时候
- 每个元素的长度小于64字节
skiplist:不满足上述两个条件就会使用跳表,具体来说是组合了map和skiplist
- map用来存储member到score的映射,这样就可以在O(1)时间内找到member对应的分数
- skiplist按从小到大的顺序存储分数
- skiplist每个元素的值都是[score,value]对
因为有了skiplist,才1能在O(logN)的时间内插入一个元素,并且实现快速的按分数范围查找元素
skiplist优势
skiplist本质上是并行的有序链表,但它克服了有序链表插入和查找性能不高的问题。它的插入和查询的时间复杂度都是O(logN)
skiplist原理
普通有序链表的插入需要一个一个向前查找是否可以插入,所以时间复杂度为O(N),比如下面这个链表插入23,就需要一直查找到22和26之间。
如果节点能够跳过一些节点,连接到更靠后的节点就可以优化插入速度:
先使用第2层链接head->7->19->26,发现26比23大,就回到19
再用第1层连接19->22->26,发现比23大,那么就插入到26之前,22之后
上面这张图就是跳表的初步原理,但一个元素插入链表后,应该拥有几层连接呢?跳表在这块的实现方式是随机的,也就是23这个元素插入后,随机出一个数,比如这个数是3,那么23就会有如下连接ÿ