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

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

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


什么是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索引层直到原始链表层都会存在该元素
  • 空间换时间,跳表查找变快了,但是要存储许多索引层,故空间开销变大了
  1. /**
  2. * 产生节点的高度。使用抛硬币
  3. *
  4. * @return
  5. */
  6. private int getRandomLevel() {
  7. //可知,元素的插入层次i从1开始自增,随机到哪一层的概率就像抛硬币一样,都是50%,故i越往后,其概率越小(每次都*0.5)
  8. //第一层概率:0.5,第二层0.5*0.5=0.25,...
  9. int lev = 1;
  10. while (random.nextInt() % 2 == 0) {
  11. lev++;
  12. }
  13. //MAX_LEVEL为跳表的最大层级
  14. return lev > MAX_LEVEL ? MAX_LEVEL : lev;
  15. }

跳表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. 深度优先算法--对DFS的一些小小的总结(一)

    提到DFS,我们首先想到的是对树的DFS,例如下面的例子:求二叉树的深度 int TreeDepth(BinaryTreeNode* root){ if(root==nullptr)return 0; ...

  2. SpringBoot 多环境配置文件切换

    背景 很多时候,我们项目在开发环境和生成环境的环境配置是不一样的,例如,数据库配置,在开发的时候,我们一般用测试数据库,而在生产环境的时候,我们是用正式的数据,这时候,我们可以利用profile在不同 ...

  3. 在JVM的新生代内存中,为什么除了Eden区,还要设置两个Survivor区

    在JVM的新生代内存中,为什么除了Eden区,还要设置两个Survivor区? 1 为什么要有Survivor区 先不去想为什么有两个Survivor区,第一个问题是,设置Survivor区的意义在哪 ...

  4. 去掉一个Vector集合中重复的元素?

    Vector newVector = new Vector();For (int i=0;i<vector.size();i++){Object obj = vector.get(i);     ...

  5. idea-中的Mark Diretory as的内容

    Sources Root:告诉idea这个文件夹及其子文件夹中包含源代码,是需要编译构建的一部分 Test Sources Root:测试源文件夹允许您将与测试相关的代码与生产代码分开.通常,源和测试 ...

  6. 给定一个奇数n,比如n=3,生成1到n平方的数,如1到9,填入九宫格,使得横竖斜的和都相等。

    对于N阶幻方,从1开始把数字从小到大按以下规则依次写入: 一.在第一行中间一列写入1 二.依次向右上方写入2.3.4...... 三.如果某数字写在了表格的某个方向外面,那就把这个数字向相反方向移动N ...

  7. 你能保证 GC 执行吗?

    不能,虽然你可以调用 System.gc() 或者 Runtime.gc(),但是没有办法保证 GC 的执行.

  8. 攻防世界 easytornado

    easytornado 进入环境就这样子 我们逐一访问看看 进入flag.txt提示flag in /fllllllllllllag我们访问fllllllllllllag看看 报了一个error,且在 ...

  9. 网络协议之:socket协议详解之Datagram Socket

    目录 简介 什么是Datagram Socket 使用socat来创建UDP服务 使用ss命令来监控Datagram Sockets 使用nc建立和UDP Socket的连接 总结 简介 上一篇文章我 ...

  10. 基于HTML5的网络拓扑图(1)

    什么是网络拓扑 网络拓扑,指构成网络的成员间特定的排列方式.分为物理的,即真实的.或者逻辑的,即虚拟的两种.如果两个网络的连接结构相同,我们就説它们的网络拓扑相同,尽管它们各自内部的物理接线.节点间距 ...