跳跃表(跳表)是什么

为什么要有跳表

正常链表只能一个一个往下走但是如果我直到我的目标位置就在链表的中部但是我还得一步一步走过去很浪费时间,所以跳表就是在正常链表的基础上添加了多步跳跃的指针。

什么是跳表

跳表(Skip List)是一种概率型的数据结构,它是基于链表的,通过创建多个层次的链表来加快搜索速度。每个节点不仅有指向下一节点的指针,还可能有指向更高层次节点的指针,从而实现快速跳跃。跳表的时间复杂度为 O(log n) 级别,适用于插入、删除和查找操作。

演示图只是为了方便,实际跳表并不一定是二分的,一个节点最初始在最底层(L0),他有75%的概率不增长层数有25%的概率往上增长一层,后续也是如此25%概率增长一层,我们的层数基本控制在log n。

以下源码来自 redis7.0
​
#define ZSKIPLIST_MAXLEVEL 32 /* Should be enough for 2^64 elements */
#define ZSKIPLIST_P 0.25   /* Skiplist P = 1/4 */
​
/* Returns a random level for the new skiplist node we are going to create.* The return value of this function is between 1 and ZSKIPLIST_MAXLEVEL* (both inclusive), with a powerlaw-alike distribution where higher* levels are less likely to be returned. */
int zslRandomLevel(void) {static const int threshold = ZSKIPLIST_P*RAND_MAX;int level = 1;while (random() < threshold)level += 1;return (level<ZSKIPLIST_MAXLEVEL) ? level : ZSKIPLIST_MAXLEVEL;
}

跳表的基本结构

跳表由以下几个部分组成:

  1. 表头(head):负责维护跳跃表的节点指针。

  2. 跳跃表节点:保存着元素值,以及多个层。

  3. :保存着指向其他元素的指针。高层的指针越过的元素数量大于等于低层的指针,为了提高查找的效率,程序总是从高层先开始访问,然后随着元素值范围的缩小,慢慢降低层次。

  4. 表尾:全部由 NULL 组成,表示跳跃表的末尾。

跳表的实现

在Redis中,跳表由 zskiplistNodezskiplist 两个结构定义。其中 zskiplistNode 结构用于表示跳跃表节点,而 zskiplist 结构则用于保存跳跃表节点的相关信息,比如节点的数量,以及指向表头节点和表尾节点的指针等等。

zskiplistNode 结构
  • 后退指针(backward):指向当前节点的前一个节点。

  • 分值(score):用于排序,跳跃表中的所有节点都按分值大小进行排序。

  • 成员对象(ele):即真正要往链表中存放的对象。

  • 层(level):每个节点都包含很多层,每一层指向的都是同一个对象。每一层包含一个前进指针和一个跨度(span),前进指针指向同一层的下一个节点,跨度表示两个节点之间的距离。

typedef struct zskiplistNode {//Zset 对象的元素值sds ele;//元素权重值double score;//后退指针struct zskiplistNode *backward;//节点的level数组,保存每层上的前向指针和跨度struct zskiplistLevel {struct zskiplistNode *forward;unsigned long span;} level[];
} zskiplistNode;
zskiplist 结构
  • header:指向跳跃表的表头节点。

  • tail:指向跳跃表的表尾节点。

  • level:记录目前跳跃表内,层数最大的那个节点的层数(表头节点的层数不计算在内)。

  • length:记录跳跃表的长度,也即是,跳跃表目前包含节点的数量(表头节点不计算在内)。

跳表的操作

跳表支持以下基本操作:

  1. 插入(Insert):插入一个元素时,从最高层开始,查找到当前节点的目标插入位置,随机生成它的层数(25%概率增长一层),然后将元素插入到跳表中并更新指针。需要使用一个数组记录该节点在各层的上一节点,用于跟新指针。

  2. 删除(Delete):删除元素时,需要最高层级开始找到对应的节点,删除并更新相关层级指针。

  3. 查找(Search):查找元素时,从高层开始向下查找,直到找到元素或到达底层。

跳表是一种以空间换时间的方案,它通过增加索引层数来提高查找效率,但同时也会占用更多的内存。在Redis中,跳表主要用于实现有序集合(Sorted Set),它能够保证元素的快速查找和有序存储。

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

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

相关文章

【自动驾驶汽车通讯协议】RGMII通信技术详解

文章目录 0. 前言1. RGMII概述1.1 RGMII说明1.2 RGMII作用&目的 2. RGMII的发展历史2.1 MII (Media Independent Interface)2.2 GMII (Gigabit Media Independent Interface)2.3 RGMII (Reduced Gigabit Media Independent Interface) 3. 架构设计3.1 接口信号3.2 信号时序…

mamba-ssm安装

注意1&#xff1a;mamba-ssm要与casual-conv1d一起安装。 注意2&#xff1a;mamba-ssm与cuda、pytorch版本要对应。需要看你下载的代码的requirements.txt causal-conv1d与mamba的whl包官网下载&#xff1a; https://github.com/Dao-AILab/causal-conv1d/releases?page3 htt…

浏览器选中文字样式

效果 学习 Chrome: 支持 ::selection。Firefox: 支持 :-moz-selection 和 ::selection。Safari: 支持 ::selection。Internet Explorer: 支持 :-ms-selection。Microsoft Edge: 支持 ::-ms-selection 和 ::selection。 代码 <!DOCTYPE html> <html lang"en&qu…

【网络安全 | 漏洞挖掘】绕过电子邮件确认实现预账户接管

未经许可,不得转载。 文章目录 正文漏洞步骤赏金正文 我测试的应用程序有多个子域名: 1、account.example.com:处理用户账户管理。 2、project.example.com:管理用户拥有或被邀请的项目。 3、org.example.com:一个新的子域,用于管理多个项目的组织。 4、collaborator.ex…

RAG实战:本地部署ragflow+ollama(linux)

1.部署ragflow 1.1安装配置docker 因为ragflow需要诸如elasticsearch、mysql、redis等一系列三方依赖&#xff0c;所以用docker是最简便的方法。 docker安装可参考Linux安装Docker完整教程&#xff0c;安装后修改docker配置如下&#xff1a; vim /etc/docker/daemon.json {…

如何免费解锁 IPhone 网络

您是否担心 iPhone 上的网络锁定&#xff1f;如果您的 iPhone 被锁定到特定运营商&#xff0c;解锁它可以连接到不同的运营商。好吧&#xff0c;我们为您准备了一份指南。 iPhone运营商免费解锁将是小菜一碟。在我们的解锁运营商 iphone 免费指南中。我们为您提供了一份简介&am…

数论问题22

题、证明&#xff0c;方程x-yz1具有无限多个正整数解(x&#xff0c;y&#xff0c;z)&#xff0c;其中x&#xff0c;y&#xff0c;z两两不同&#xff0c;且任意两个之积都被第三个整除。 分析与证明:假设方程的正整数解两两不同&#xff0c;并且任意两个之积都被第三个整除。即 …

人工智能安全——联邦学习的安全攻击与防护

参考论文FedMDFG: Federated Learning with Multi-Gradient Descent and Fair Guidance (AAAI-2023) 背景 随着人工智能技术的飞速发展&#xff0c;隐私保护和数据安全越来越受到重视。联邦学习&#xff08;Federated Learning, FL&#xff09;作为一种分布式隐私保护的机器学…

【51项目】51单片机自制小霸王游戏机

视频演示效果: 纳新作品——小霸王游戏机 目录: 目录 视频演示效果: 目录: 前言:

R机器学习:神经网络算法的理解与实操,实例解析

神经网络算法是一种模仿生物神经网络&#xff08;尤其是人脑&#xff09;结构和功能的算法。它由大量相互连接的节点&#xff08;称为神经元&#xff09;组成&#xff0c;这些神经元组织成层&#xff0c;通过传递信号来处理信息。神经网络算法在机器学习、人工智能等领域中扮演…

wsl linux CUDA安装、卸载、清理、版本降级、升级过程详解

目录 1 前言2 卸载与重新安装2.1 列出所有与 CUDA 相关的包2.2 卸载 CUDA2.3 删除残留文件2.4 移除 CUDA 仓库包2.5 删除仓库目录2.6 移除所有 CUDA 相关包2.7 删除 CUDA 的优先级配置文件2.8 查看所有 APT 源中的 CUDA 条目2.9 移除或禁用不需要的 CUDA 仓库源2.10 删除所有 A…

牛客网刷题 ——C语言初阶——OR76 两个整数二进制位不同个数

1. 牛客网题目&#xff1a;OR76 两个整数二进制位不同个数 牛客网OJ链接 描述&#xff1a; 输入两个整数&#xff0c;求两个整数二进制格式有多少个位不同 输入描述&#xff1a;两个整数 输出描述&#xff1a;二进制不同位的个数 示例1 输入&#xff1a;22 33 输出&#xff1a…

【AWS SDK PHP】This operation requests `sigv4a` auth schemes 问题处理

使用AWS SDK碰到的错误&#xff0c;其实很简单&#xff0c;要装个扩展库 保持如下 Fatal error: Uncaught Aws\Auth\Exception\UnresolvedAuthSchemeException: This operation requests sigv4a auth schemes, but the client currently supports sigv4, none, bearer, sigv4-…

设计模式 结构型 装饰器模式(Decorator Pattern)与 常见技术框架应用 解析

装饰器模式&#xff08;Decorator Pattern&#xff09;&#xff0c;又称为包装器模式&#xff08;Wrapper Pattern&#xff09;&#xff0c;是一种结构型设计模式。它允许在不改变原有对象结构的基础上&#xff0c;动态地给对象添加一些新的职责&#xff08;即增加其额外功能&a…

<论文>聊聊初代LLaMA

一、摘要 本文介绍来自Meta的论文《LLaMA: Open and Efficient Foundation Language Models》&#xff0c;这篇2023年的研究发布了开源的LLaMA系列大模型&#xff0c;轰动一时。 译文&#xff1a; 我们推出了 LLaMA&#xff0c;一系列参数规模从 70 亿到 650 亿的基础语言模型。…

【bluedroid】A2dp Source播放流程源码分析(4)

接上集分析:【bluedroid】A2dp Source播放流程源码分析(3)-CSDN博客 蓝牙和AUDIO之间的接口 蓝牙和audio之间的通信是通过socket,管理socket中的文件是UIPC,UIPC管理两条socket。 A2DP_CTRL_PATH /data/misc/bluedroid/.a2dp_ctrl A2DP_DATA_PATH /data/misc/bluedroid…

React 中结合 antd 的 Input 组件实现防抖输入

在 React 中结合 antd 的 Input 组件实现防抖输入&#xff0c;可以通过以下几种方式实现&#xff1a; 1. 使用 useEffect 和 setTimeout 代码示例 import React, { useState, useEffect } from "react"; import { Input } from "antd";const DebouncedI…

把vue项目或者vue组件发布成npm包或者打包成lib库文件本地使用

将vue项目发布成npm库文件&#xff0c;第三方通过npm依赖安装使用&#xff1b;使用最近公司接了一个项目&#xff0c;这个项目需要集成到第三方页面&#xff0c;在第三方页面点击项目名称&#xff0c;页面变成我们的项目页面&#xff1b;要求以npm库文件提供给他们&#xff1b;…

STM32 NOR FLASH(SPI FLASH)驱动移植(2)

2&#xff09;FLASH 读取函数 /* * brief 读取 SPI FLASH * note 在指定地址开始读取指定长度的数据 * param pbuf : 数据存储区 * param addr : 开始读取的地址(最大 32bit) * param datalen : 要读取的字节数(最大 65535) * retval 无 */ void norflash_read(uint8_t *pbuf…

自从学会Git,感觉打开了一扇新大门

“同事让我用 Git 提交代码&#xff0c;我居然直接把项目文件压缩发过去了……”相信很多初学者都经历过类似的窘境。而当你真正掌握 Git 时&#xff0c;才会发现它就像一本魔法书&#xff0c;轻松解决代码管理的种种难题。 为什么 Git 能成为程序员的标配工具&#xff1f;它究…