点赞再看,养成习惯,微信搜索「小大白日志」关注这个搬砖人。

文章不定期同步公众号,还有各种一线大厂面试原题、我的学习系列笔记。

广州这边封闭式管理好久了,今天终于周末可以出去溜溜了


什么是zset

zset是redis中一种有序、不重复的数据类型,每个元素都有一个分值,它可用于实现排行榜单,其底层采用压缩表ziplist或跳表skiplist的数据结构实现

zset的两种数据结构

  • 压缩表ziplist

当redis插入第一个元素时,同时满足以下条件,就会以ziplist创建跳表

  • 节点数量<128 (可通过server.zset_max_ziplist_entries设置)
  • 节点的长度<64(可通过server.zset-max-zip以上任一个,都会list-value设置)

当选择用ziplist实现zset后,以后插入的节点若不满足以上任一个条件,就会转为skiplist

  • 跳表skiplist

跳表的本质是一个多层链表,它能快速地查询、插入、删除【时间复杂度均为O(logn)】,所以它的查询速度媲美平衡二叉树,而且它的数据结构比平衡二叉树简单,结构示意图如下:



特点:

  • 跳表的最底层拥有所有的元素
  • 跳表每一层都是一个链表,除了最底层是原始链表,层次逐渐往上可分别划分为一级索引层、二级索引层...
  • 跳表插入元素时,会先随机生成出一个“层次数字”,然后元素会插入到这个层次的所有底层,直到原始链表层
  • 如果一个元素存在与某个索引层,那么这个元素也会存在于低于它的所有索引下层,如元素在第99索引层,那么由上到下从99索引层直到原始链表层都会存在该元素
  • 空间换时间,跳表查找变快了,但是要存储许多索引层,故空间开销变大了
 /**
* 产生节点的高度。使用抛硬币
*
* @return
*/
private int getRandomLevel() {
//可知,元素的插入层次i从1开始自增,随机到哪一层的概率就像抛硬币一样,都是50%,故i越往后,其概率越小(每次都*0.5)
//第一层概率:0.5,第二层0.5*0.5=0.25,...
int lev = 1;
while (random.nextInt() % 2 == 0) {
lev++;
}
//MAX_LEVEL为跳表的最大层级
return lev > MAX_LEVEL ? MAX_LEVEL : lev;
}

跳表skiplist

  • 插入节点

    • 插入的时间复杂度为O(logn),每次插入都会先查找到要插入的位置(查找的时间复杂度就已经是【O(logn)】了,找到后直接插入【O(1)】,所以总的为【O(logn)】),删除也是同理为O(logn)
    • 每个节点的插入层次是通过getRandomLevel()随机出来的,插入层次互不影响

      以下模拟节点插入:

  • 查找

查找节点时,从高索引层往低索引层查找:

一开始元素在高层从链表由前往后查找,直到要查找的目标元素在该层的某两个相邻元素之间,就会往下跳到下层的同一个位置,继续从同一位置向链表尾方向遍历查询->重复上面的过程,直到查找到目标元素

查找时每一层都跳过部分元素,进而加快了查找效率,以下模拟节点查找:

OK,如果文章哪里有错误或不足,欢迎各位留言。

创作不易,各位的「三连」是二少创作的最大动力!我们下期见!

redis的zset数据结构:跳表的更多相关文章

  1. Redis源码研究--跳表

    -------------6月29日-------------------- 简单看了下跳表这一数据结构,理解起来很真实,效率可以和红黑树相比.我就喜欢这样的. typedef struct zski ...

  2. Redis中为什么使用跳表---------转自http://blog.csdn.net/u010412301/article/details/64923131

    最近在研究数据库的一些底层实现,百度的面试官问到了跳表,当时没有回答上来,在csdn上看到了这篇文章,感觉写的比较好,希望大家可以多多交流. Redis里面使用skiplist是为了实现sorted ...

  3. 聊聊Mysql索引和redis跳表 ---redis的有序集合zset数据结构底层采用了跳表原理 时间复杂度O(logn)(阿里)

    redis使用跳表不用B+数的原因是:redis是内存数据库,而B+树纯粹是为了mysql这种IO数据库准备的.B+树的每个节点的数量都是一个mysql分区页的大小(阿里面试) 还有个几个姊妹篇:介绍 ...

  4. Redis 学习笔记(篇三):跳表

    跳表 跳表(skiplist)是一种有序的数据结构,是在有序链表的基础上发展起来的. 在 Redis 中跳表是有序集合(sort set)的底层实现之一. 说到 Redis 中的有序集合,是不是和 J ...

  5. Redis 的底层数据结构(跳跃表)

    字典相对于数组,链表来说,是一种较高层次的数据结构,像我们的汉语字典一样,可以通过拼音或偏旁唯一确定一个汉字,在程序里我们管每一个映射关系叫做一个键值对,很多个键值对放在一起就构成了我们的字典结构. ...

  6. 深入理解跳表在Redis中的应用

    本文首发于:深入理解跳表在Redis中的应用微信公众号:后端技术指南针持续输出干货 欢迎关注 前面写了一篇关于跳表基本原理和特性的文章,本次继续介绍跳表的概率平衡和工程实现, 跳表在Redis.Lev ...

  7. 红黑树、B(+)树、跳表、AVL等数据结构,应用场景及分析,以及一些英文缩写

    在网上学习了一些材料. 这一篇:https://www.zhihu.com/question/30527705 AVL树:最早的平衡二叉树之一.应用相对其他数据结构比较少.windows对进程地址空间 ...

  8. 跳表(SkipList)设计与实现(Java)

    微信搜一搜「bigsai」关注这个有趣的程序员 文章已收录在 我的Github bigsai-algorithm 欢迎star 前言 跳表是面试常问的一种数据结构,它在很多中间件和语言中得到应用,我们 ...

  9. 算法进阶面试题06——实现LFU缓存算法、计算带括号的公式、介绍和实现跳表结构

    接着第四课的内容,主要讲LFU.表达式计算和跳表 第一题 上一题实现了LRU缓存算法,LFU也是一个著名的缓存算法 自行了解之后实现LFU中的set 和 get 要求:两个方法的时间复杂度都为O(1) ...

随机推荐

  1. 如何巧妙使用vim处理文件

    一系列流程书写如何用vim巧妙处理文件 1. 创建两个待处理的文件 root@ubuntu:/home/watson/real-watson# touch left right 2. 简单增补文件内容 ...

  2. C#拾遗补阙【01】:字符串

    一.string是特殊的引用类型 ​ 众所周知,string是引用类型.为什么string是引用类型,最简单的方法,f12转到string的定义.显而易见,string的本质是类,字符串存储在堆中,而 ...

  3. 微服务部署 docker-compose

    1.docker-maven-plugin 介绍 在我们持续集成过程中,项目工程一般使用 Maven 编译打包,然后生成镜像,通过镜像上线,能够大大提供上线效率,同时能够快速动态扩容,快速回滚,着实很 ...

  4. mysql行锁、表锁。乐观锁,悲观锁

    锁定用于确保事务完整性和数据库一致性. 锁定可以防止用户读取其他用户正在更改的数据,并防止多个用户同时更改相同的数据. 如果不使用锁定,数据库中的数据可能在逻辑上变得不正确,而针对这些数据进行查询可能 ...

  5. spring-boot-learning-RabbitMQ

    为什么需要MQ??? 异步处理: 场景: 用户注册后,需要发注册邮件和注册短信,传统的做法有两种 1.串行的方式 2.并行的方式` 用户注册-发送注册邮箱-发送注册短信都完成之后才结束返回给客户端 邮 ...

  6. kafka中的回调函数

    kafka客户端中使用了很多的回调方式处理请求.基本思路是将回调函数暂存到ClientRequest中,而ClientRequest会暂存到inFlightRequests中,当返回response的 ...

  7. C++中类所占的内存大小以及成员函数的存储位置

    类所占内存的大小是由成员变量(静态变量除外)决定的,虚函数指针和虚基类指针也属于数据部分,成员函数是不计算在内的.因为在编译器处理后,成员变量和成员函数是分离的.成员函数还是以一般的函数一样的存在.a ...

  8. (stm32f103学习总结)—USART串口通信

    一. USART简介 USART即通用同步异步收发器,它能够灵活地与外部设备进行全双工 数据交换,满足外部设备对工业标准 NRZ 异步串行数据格式的要求. UART即通用异步收发器,它是在USART基 ...

  9. stm32CubeMX+keil5好用还是stm32CubeID好用

    cubemx是图形配置软件, 可以节省往常配置IO口的时间, cubemx主推hal库, 它是生成keil工程的工具 cubemx生成的工程可以用keilv5编程软件来编辑... 用Cube mx定义 ...

  10. 前端文件上传-javascript-ajax

    书写是为了更好的记忆. 方案一:form表单上传 该方案优点是支持好,缺点刷新页面. <form action="url" method="post" e ...