


23首先和7比较,再和19比较,比它们都大,继续向后比较. 但23和26比较的时候,比26要小,因此回到下面的链表(原链表),与22比较. 23比22要大,沿下面的指针继续向后和26比较.23比26小,说明待查数据23在原链表中不存在,而且它的插入位置应该在22和26之间.
skiplist与平衡树、哈希表的比较:
skiplist和各种平衡树(如AVL、红黑树等)的元素是有序排列的,而哈希表不是有序的.因此,在哈希表上只能做单个key的查找,不适宜做范围查找.所谓范围查找,指的是查找那些大小在指定的两个值之间的所有节点. 在做范围查找的时候,平衡树比skiplist操作要复杂.在平衡树上,我们找到指定范围的小值之后,还需要以中序遍历的顺序继续寻找其它不超过大值的节点.如果不对平衡树进行一定的改造,这里的中序遍历并不容易实现.而在skiplist上进行范围查找就非常简单,只需要在找到小值之后,对第1层链表进行若干步的遍历就可以实现. 平衡树的插入和删除操作可能引发子树的调整,逻辑复杂,而skiplist的插入和删除只需要修改相邻节点的指针,操作简单又快速. 从内存占用上来说,skiplist比平衡树更灵活一些.一般来说,平衡树每个节点包含2个指针(分别指向左右子树),而skiplist每个节点包含的指针数目平均为1/(1-p),具体取决于参数p的大小.如果像Redis里的实现一样,取p=1/4,那么平均每个节点包含1.33个指针,比平衡树更有优势. 查找单个key,skiplist和平衡树的时间复杂度都为O(log n),大体相当;而哈希表在保持较低的哈希值冲突概率的前提下,查找时间复杂度接近O(1),性能更高一些.所以我们平常使用的各种Map或dictionary结构,大都是基于哈希表实现的. 从算法实现难度上来比较,skiplist比平衡树要简单得多.
当数据较少时,sorted set是由一个ziplist来实现的. 当数据多的时候,sorted set是由一个dict + 一个skiplist来实现的.简单来讲,dict用来查询数据到分数的对应关系,而skiplist用来根据分数查询数据(可能是范围查找)
zset-max-ziplist-entries 128zset-max-ziplist-value 64
在如下两个条件之一满足的时候,ziplist会转成zset(具体的触发条件参见t_zset.c中的zaddGenericCommand相关代码):
当sorted set中的元素个数,即(数据, score)对的数目超过128的时候,也就是ziplist数据项超过256的时候.
当sorted set中插入的任意一个数据的长度超过了64的时候.
Redis为什么用skiplist而不用平衡树?
skiplist占用内存低
skiplist的范围遍历性能比平衡树好
数据结构实现难度较低
文章转载自没意思先生,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




