Redis数据结构 — SkipList

news2024/11/24 15:18:19

目录

跳表结构设计

跳表节点结构设计

跳表节点查询过程

跳表节点层数设置

为什么用跳表不用红黑树?

跳表平均指针数目为1/(1-p)公式推导


跳表的优势是能支持平均 O(logN) 复杂度的节点查找,支持进行高效的范围查询

SkipList(跳表)首先是链表,但与传统链表相比有几点差异:

  • 元素按照升序排列存储,跳表结构体中会包含排序所需的值
  • 前向节点可能包含多个指针,指针跨度不同。

跳表结构设计

跳表是在链表基础上改进过来的,实现了一种「多层」的有序链表,这样的好处是能快读定位数据。

跳表结构里包含:

  • 跳表的头尾节点,便于在O(1)时间复杂度内访问跳表的头节点和尾节点;
  • 跳表的长度,便于在O(1)时间复杂度获取跳表节点的数量;
  • 跳表的最大层数,便于在O(1)时间复杂度获取跳表中层高最大的那个节点的层数量;

跳表节点结构设计

 图中头节点有 L1~L3 三个头指针,分别指向了不同层级的节点,然后每个层级的节点都通过指针连接起来:

  • L1 层级共有 5 个节点,分别是节点1、2、3、4、5;
  • L2 层级共有 3 个节点,分别是节点1、3、5;
  • L3 层级只有 1 个节点,也就是节点1、5 。

跳表节点查询过程

查找一个跳表节点的过程时,跳表会从头节点的最高层开始,逐一遍历每一层。在遍历某一层的跳表节点时,会用跳表节点中的 SDS 类型的元素和元素的权重来进行判断,共有两个判断条件:

  • 如果当前节点的权重「小于」要查找的权重时,跳表就会访问该层上的下一个节点。
  • 如果当前节点的权重「等于」要查找的权重时,并且当前节点的 SDS 类型数据「小于」要查找的数据时,跳表就会访问该层上的下一个节点。
  • 若上面两个条件都不满足,或者下一个节点为空时,跳表就会使用目前遍历到的节点的 level 数组里的下一层指针,然后沿着下一层指针继续查找,这就相当于跳到了下一层接着查找。

情景有个 3 层级的跳表,查找【元素:abcd,权重:4】的节点,查找的过程是这样的

  • 先从头节点的最高层开始,L2 指向了「元素:abc,权重:3」节点,这个节点的权重比要查找节点的小,所以要访问该层上的下一个节点;
  • 但是该层的下一个节点是空节点( leve[2]指向的是空节点),于是就会跳到「元素:abc,权重:3」节点的下一层去找,也就是 leve[1];
  • 「元素:abc,权重:3」节点的 leve[1] 的下一个指针指向了「元素:abcde,权重:4」的节点,然后将其和要查找的节点比较。虽然「元素:abcde,权重:4」的节点的权重和要查找的权重相同,但是当前节点的 SDS 类型数据「大于」要查找的数据,所以会继续跳到「元素:abc,权重:3」节点的下一层去找,也就是 leve[0];
  • 「元素:abc,权重:3」节点的 leve[0] 的下一个指针指向了「元素:abcd,权重:4」的节点,该节点正是要查找的节点,查询结束。

跳表节点层数设置

跳表的相邻两层的节点数量最理想的比例是 2:1查找复杂度可以降低到 O(logN)

Redis实现做法是跳表在创建节点时候,会生成范围为[0-1]的一个随机数,如果这个随机数小于 0.25(相当于概率 25%),那么层数就增加 1 层,然后继续生成下一个随机数,直到随机数的结果大于 0.25 结束,最终确定该节点的层数

最大层数有阈值限制,ZSKIPLIST_MAXLEVEL控制,Redis 7.0 定义为 32,Redis 5.0 定义为 64,Redis 3.0 定义为 32。

创建跳表时,就会直接创建ZSKIPLIST_MAXLEVEL层高的头节点,源码如下:

/* Create a new skiplist. */
zskiplist *zslCreate(void) {
    int j;
    zskiplist *zsl;

    zsl = zmalloc(sizeof(*zsl));
    zsl->level = 1;
    zsl->length = 0;
    zsl->header = zslCreateNode(ZSKIPLIST_MAXLEVEL,0,NULL);
    for (j = 0; j < ZSKIPLIST_MAXLEVEL; j++) {
        zsl->header->level[j].forward = NULL;
        zsl->header->level[j].span = 0;
    }
    zsl->header->backward = NULL;
    zsl->tail = NULL;
    return zsl;
}

为什么用跳表不用红黑树?

  • 从内存占用上来比较,跳表比平衡树更灵活一些。平衡树每个节点包含 2 个指针(分别指向左右子树),而跳表每个节点包含的指针数目平均为 1/(1-p),具体取决于参数 p 的大小。如果像 Redis里的实现一样,取 p=1/4,那么平均每个节点包含 1.33 个指针,比平衡树更有优势。
  • 在做范围查找的时候,跳表比平衡树操作要简单
  • 从算法实现难度上来比较,跳表比平衡树要简单得多。平衡树的插入和删除操作可能引发子树的调整,逻辑复杂,而跳表的插入和删除只需要修改相邻节点的指针,操作简单又快速。

跳表平均指针数目为1/(1-p)公式推导

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/754348.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

idea-控制台输出乱码问题

idea-控制台输出乱码问题 现象描述&#xff1a; 今天在进行IDEA开发WEB工程调式的时候控制台日志输出了乱码&#xff0c;如下截图 其实开发者大多都知道乱码是 编码不一致导致的&#xff0c;但是有时候就是不知到哪些地方不一致&#xff0c;今天我碰到的情况可能和你的不相同…

【C++】多态及原理

文章目录 1.多态的概念2.多态的定义及实现2.1多态的构成条件2.2虚函数的重写2.3析构函数的重写2.4 C11 override和 final2.5重载、重写(覆盖)、重定义(隐藏)的对比 3.抽象类3.1定义 4.多态的原理4.1虚函数表 虚表单继承的虚表多继承的虚表问答题 1.多态的概念 多态&#xff0c;…

(数组与矩阵) 剑指 Offer 03. 数组中重复的数字 ——【Leetcode每日一题】

❓ 剑指 Offer 03. 数组中重复的数字 难度&#xff1a;简单 找出数组中重复的数字。 在一个长度为 n 的数组 nums 里的所有数字都在 0&#xff5e;n-1 的范围内。数组中某些数字是重复的&#xff0c;但不知道有几个数字重复了&#xff0c;也不知道每个数字重复了几次。请找出…

新功能: 全新的UI视图、搜索设置和强大的API特性

我们在ftrack Studio中引入的一些超赞的新功能&#xff0c;旨在将用户体验提升到一个新的水平&#xff01;准备好提高生产效率、优化任务流程&#xff0c;并获得有价值的见解&#xff0c;以便为你的所有项目做出数据驱动的决策。 本月&#xff0c;我们为ftrack Studio带来了几个…

PyLab绘制曲线图

PyLab 是一个面向 Matplotlib 的绘图库接口&#xff0c;其语法和 MATLAB 十分相近。它和 Pyplot 模快都够实现 Matplotlib 的绘图功能。PyLab 是一个单独的模块&#xff0c;随 Matplotlib 软件包一起安装&#xff0c;该模块的导包方式和 Pyplot 不同&#xff0c;如下所示&#…

SAP CAP篇十:理解Fiori UI的Annoation定义

本文目录 本系列此前的文章官方文档和基础概念SAP CAP对Fiori UI的支持package.json的新增内容Annotation定义List Page 生成的Edmx文件 对应代码及branch 本系列此前的文章 SAP CAP篇一: 快速创建一个Service&#xff0c;基于Java的实现 SAP CAP篇二&#xff1a;为Service加上…

青岛大学_王卓老师【数据结构与算法】Week05_12_队列的类型定义_学习笔记

本文是个人学习笔记&#xff0c;素材来自青岛大学王卓老师的教学视频。 一方面用于学习记录与分享&#xff0c; 另一方面是想让更多的人看到这么好的《数据结构与算法》的学习视频。 如有侵权&#xff0c;请留言作删文处理。 课程视频链接&#xff1a; 数据结构与算法基础…

【学习笔记】[CTSC2017] 网络

我的评价是毒瘤&#x1f605; 首先想到的肯定是原树上的直径。 于是得到第一个结论&#xff1a;这条边的两个端点一定在直径上。 第二个结论&#xff1a;每个点距离最远的那个点是直径的两个端点之一。 发现直径上形成了一个环。显然这个环的长度应该 ≥ L \ge L ≥L&#…

Mysql分区表----分类、优势、特点、优点

范围分区&#xff08;Range Partitioning、哈希分区&#xff08;Hash Partitioning&#xff09;列 表分区&#xff08;List Partitioning&#xff09;、键值分区&#xff08; Key partition &#xff09; 文章目录 mysql分区表概述&#xff1a;MYSQL分区表简单而言就是将一张大…

跨域问题解决

由于同源策略&#xff0c;需要协议&#xff0c;域名&#xff0c;端口三个都相同才能进行访问&#xff0c;是一种浏览器的保护策略 CORS:Cross Origin Resource Sharing SpringBoot 项目中解决跨域 1.在目标方法中加入CrossOrigin注解 2.添加一种过滤器 分别是允许哪些域&#…

分享几种在家就能做的网赚方式,下班暑假都可以做的副业推荐

在当前的互联网时代中&#xff0c;网上赚钱已经成为受到广泛关注的一个话题。越来越多的人渴望通过利用互联网来实现经济上的自由&#xff0c;然而&#xff0c;同时也面临一些风险和挑战。 尽管网上有很多兼职赚钱的机会&#xff0c;但并不是所有方式都可信赖。有些机会可能会…

JVM_00000

JVM 所谓虚拟机&#xff08;Virtual Machine&#xff09;就是一台虚拟的计算机。它是一款软件&#xff0c;用来执行一系列虚拟计算机指令。大体上&#xff0c;虚拟机可以分为系统虚拟机和程序虚拟机。 Visual Box&#xff0c;VMware就属于系统虚拟机&#xff0c;它们完全是对物…

【动手学习深度学习--逐行代码解析合集】18网络中的网络(NiN)

【动手学习深度学习】逐行代码解析合集 18网络中的网络&#xff08;NiN&#xff09; 视频链接&#xff1a;动手学习深度学习–网络中的网络&#xff08;NiN&#xff09; 课程主页&#xff1a;https://courses.d2l.ai/zh-v2/ 教材&#xff1a;https://zh-v2.d2l.ai/ 1、NiN网络…

IDE/VS项目属性中的 <字符集> 配置项,它到底是干什么用的?

文章目录 概述对配置项的基础测试VS默认的字符集配置Unicode字符集和多字节字符集是否影响文本编辑器 使VS像记事本那样显示文件编码VS下编译UTF-8无BOM的代码文件VS可以搞定ANSI和带BOM的源代码文件VS搞不定UTF-8无BOM的源代码文件乱码字符是怎么翻译出来的?猜猜看再起航 使V…

解决windows上端口占用问题

在开发中总会碰到端口占用问题&#xff0c;最后导致我们项目或服务无法正常启动。 解决方案如下&#xff1a; # 1.根据端口号查进程 例如8082端口 netstat -aon | findstr :8082 # 2.根据进程id查应用名 tasklist|findstr "11376" # 3.根据pid删除进程 taskkill …

检测到错误页面web应用服务器版本信息泄露

详细描述 Web服务器未能正确处理异常请求导致Web服务器版本信息泄露&#xff0c;攻击者收集到服务器信息后可进行进一步针对性攻击。 解决办法 临时修复建议如下&#xff1a; 1、关闭web服务器错误提示。 2、关闭运行平台的错误提示。 3、建立错误机制&#xff0c;不要把真实…

python numpy axis=0,1,2, 分清楚

理解维度问题&#xff0c;记忆右边图片坐标的0,1&#xff0c;2&#xff0c; 就记住了计算方向问题&#xff0c;每个矩阵想象一张图片&#xff0c;多个图片叠加&#xff0c; 哪个维度做&#xff0c;哪个维度就被降维度1&#xff0c;默认无 所以 &#xff08;4,3&#xff0c;2&am…

linux系统管理:常用命令和技巧

目录 0 前言 1 sudo and su 1.1 su: 切换用户 1.2 sudo: 切换用户 2 权限设置&#xff1a;chmod, chown 2.1 chmod&#xff1a;访问权限设置 2.2 chown&#xff1a;设置文件或目录的主人 2.3 chgrp&#xff1a;设计文件或者目录属于哪个组 2.4 查询组成员 2.5 查询某…

搭建微服务工程 【详细步骤】

一、准备阶段 &#x1f349; 本篇文章用到的技术栈 mysqlmybatis[mp]springbootspringcloud alibaba 需要用到的数据库 订单数据库: SET NAMES utf8mb4; SET FOREIGN_KEY_CHECKS 0;-- ---------------------------- -- Table structure for shop_order -- --------------…

Nacos服务注册和配置中心(Config,Eureka,Bus)1

SCA(Spring Cloud Alibaba)核心组件 Spring Cloud是若干个框架的集合&#xff0c;包括spring-cloud-config、spring-cloud-bus等近20个子项目&#xff0c;提供了服务治理、服务网关、智能路由、负载均衡、断路器、监控跟踪、分布式消息队列、配置管理等领域的解决方案,Spring C…