Redis zset(有序列表)

zset 可能是Redis提供的最有特色的数据结构,它也是在面试中面试最爱问的数据结构,如图所示,它类似Java的SortedSet和HashMap的结合体,一方面它是一个set,保证了内部value的唯一性,另一个方面它可以给每个value赋予一个score,代表这个value的排序权重。它的内部实现用的是一种跳跃列表的数据结构。
在这里插入图片描述

zset中最后一个value被移除后,数据结构被自动删除,内存被回收。

zset可以用来存储粉丝列表,value值是粉丝的用户id,score 是关注时间,我们可以对粉丝列表按关注时间进行排序。

zset还可以用来存储学生的成绩,value值是学生的id,score 是他的考试成绩,我们对成绩按分数进行排序就可以得到他的名次。

【跳跃列表】
zset内部的排序功能是通过“跳跃列表”数据结构来实现的,它的结构非常特殊,也比较复杂。

因为zset 要支持随机的插入和删除,所以它不宜使用数组来表示,我们先看一个普通的链表数据结构,如图下:
在这里插入图片描述
我们需要这个链表按照score值进行排序,这意味着当有新元素需要插入时,要定位到特定位置的插入点,这样才可以继续保证链表是有序的,通常我们会通过二分查找来找到插入点,但是二分查找的对象必须是数组,只有数组才可以支持快速位置定位,链表做不到,那该怎么办呢?

假设有一家创业公司,刚开始只有几个人,团队成员之间人人平等,都是联合创始人。随着公司的成长,人数渐渐变多,团队沟通成本随之增加,这时候就会引入组长制,对团队进行划分,每个团队会有一个组长,开会的时候分团队进行,多个组长之间还会有自己的会议安排。当公司规模进一步扩展,需要再增加一个层级-----部门,每个部门会从组长列表中推选出一个代表作为组长。部长们之间还会有自己的高层会议安排。

跳跃列表就类似于这种层机制,最下面一层所有的元素都会串起来,然后每隔几个元素挑选出一个代表,再将这几个代表使用另一级指针串起来,然后在这些代表里再挑出二级代表,再串起来。最终就形成了金字塔结构。

想想你老家在世界地图中的位置:亚洲->中国->某省->某市->某县->某镇->某村->门牌号,也是这样一个结构。

跳跃列表之所以跳跃,是因为内部的元素可能身兼数职,如下图,中间的这个元素,同时处于L0,L1和L2层中,可以快速在不同层次之间进行跳跃。

在这里插入图片描述

定位插入点时,先在顶层进行定位,然后下潜到下一级定位,一直下潜到最底层找到合适的位置,将新元素插入进去,你也许会问,那新元素如何才有机会身兼数职呢?

跳跃列表采取一个随机策略来决定新元素可以兼职到第几层。

首先其位于L0层的概率肯定是100%,而兼职到L1层只有50%的概率,到L2层只有25%的概率,到L3层只有12.5%的概率,以此类推,一直随机到最顶层L31层。绝大多数元素都过不了几层,只有极少数元素可以深入到顶层,列表中的元素越多,能够深入的层次越深,元素能进入到顶层的可能性会越大。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蓝颜~岁月

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值