数据结构-05-跳表SkipList

1-什么是跳表

       跳表SkipList是一种随机化的数据结构,基于并联的链表,实现简单,插入、删除、查找的复杂度均为 O(logN)(大多数情况下,因为是实现上是概率问题),因为其性能匹敌红黑树且实现较为简单,因此在很多著名项目都用 SkipList 来代替红黑树,例如Redis中的有序集合zset 的底层存储结构就是用的skiplist。
        跳跃列表由 William Pugh 发明。他在 Communications of the ACM发表了《Skip lists: a probabilistic alternative to balanced trees》,在其中详细描述了他的工作。

假设原始链表的数据如下:链表中存储的数据是有序的。

       我们知道这种链表结构查询数据的时间复杂度是O(n)。但是如果我们对链表建立"索引",把节点数据提取出来放在上一级(索引层),这样是不是就可以提高查询效率了呢?比如我们查找元素83;如果按照原始链表,要查询8个节点,采用下面这个结构,只需要查询5个节点。如果数据量越大,优势就更加明显。

这种链表加多级索引的结构,就是跳表。

2-跳表的查询

        我们知道,在一个单链表中查询某个数据的时间复杂度是O(n)。那么跳表的时间复杂度是多少呢?
      假设每两个结点会抽出一个结点作为上一级索引的结点,那第一级索引的结点个数大约就是n/2,第二级索引的结点个数大约就是n/4,第三级索引的结点个数大约就是n/8,依次类推,也就是说,第k级索引的结点个数是第k-1级索引的结点个数的1/2,第k索引结点的个数就是n/(2^k)。
       假设最高级索引有两个节点,最高级索引是k,总节点数是n,那么n/(2^k)=2,k=logn -1(以2为底的对数)。如果包含原始链表这一层,整个跳表的高度就是logn。我们在跳表中查询某个数据的时候,如果每一层都要遍历m个结点,那在跳表中查询一个数据的时间复杂度就是O(m*logn)。一般m是常数,所以在跳表中查询任意数据的时间复杂度就是O(logn)。这个时间复杂度是不是跟二分查找一样,很高效了。但是这种效率的提升,是以空间换时间的理念来实现的。

       假设我们每两个节点抽取一个,需要多使用n/2+n/4+n/8…+8+4+2=n-2。跳表的空间复杂度是O(n)。也就是说,如果将包含n个结点的单链表构造成跳表,我们需要额外再用接近n个结点的存储空间。假设我们每3个节点抽取一个,总的索引结点大约就是n/3+n/9+n/27+…+9+3+1=n/2,空间复杂度还是O(n),但比上面的每两个结点抽一个结点的索引构建方法,要减少了一半的索引结点存储空间。

        其实我们不必太在意索引占用的额外空间,因为实际的软件开发中,原始链表中存储的有可能是很大的对象,而索引结点只需要存储关键值和几个指针,并不需要存储对象,所以当对象比索引结点大很多时,那索引占用的额外空间就可以忽略了。

3-跳表的插入-删除-索引的动态更新

       插入:在单链表中,一旦定位好要插入的位置,插入结点的时间复杂度是很低的,就是O(1)。但是,这里为了保证原始链表中数据的有序性,我们需要先找到要插入的位置,这个查找操作就会比较耗时O(n)。但是,对于跳表来说,我们讲过查找某个结点的的时间复杂度是O(logn),所以这里查找某个数据应该插入的位置,方法也是类似的,时间复杂度也是O(logn)

       删除:如果这个结点在索引中也有出现,我们除了要删除原始链表中的结点,还要删除索引中的。因为单链表中的删除操作需要拿到要删除结点的前驱结点,然后通过指针操作完成删除。所以在查找要删除的结点的时候,一定要获取前驱结点。

       索引动态更新:当我们不停地往跳表中插入数据时,如果我们不更新索引,就有可能出现某2个索引结点之间数据非常多的情况。极端情况下,跳表还会退化成单链表。作为一种动态数据结构,我们需要某种手段来维护索引与原始链表大小之间的平衡,也就是说,如果链表中结点多了,索引结点就相应地增加一些,避免复杂度退化,以及查找、插入、删除操作性能下降。
       当我们往跳表中插入数据的时候,我们可以选择同时将这个数据插入到部分索引层中。如何选择加入哪些索引层呢?我们通过一个随机函数,来决定将这个结点插入到哪几级索引中,比如随机函数生成了值K,那我们就将这个结点添加到第一级到第K级这K级索引中。随机函数的选择很有讲究,从概率上来讲,能够保证跳表的索引大小和数据大小平衡性,不至于性能过度退化。

4-redis跳表使用

       Redis中的有序集合zset 的底层存储结构就是用的skiplist,为何不使用红黑树等平衡树?主要原因有以下几点:

1-高效的查找操作:跳表通过建立多层索引,可以在有序集合中实现快速的查找操作。相比于传统的平衡树结构(如红黑树),跳表的查找操作具有更低的时间复杂度,平均情况下为O(log n)。
2-简单且易于实现:相对于其他复杂的数据结构(如红黑树或AVL树),跳表的实现相对简单且容易理解。它没有复杂的平衡调整操作,只需通过维护索引层来保持有序性和高效性。
3-空间效率较高:跳表通过层级结构来建立索引,每个节点只需额外存储少量的指针信息。相比于一些平衡树结构,跳表在空间使用上通常更加高效。
       还有一个业务功能原因:对于按照区间查找数据ZRANGE这个操作,跳表可以做到O(logn)的时间复杂度定位区间的起点,然后在原始链表中顺序往后遍历就可以了。这样做非常高效。

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

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

相关文章

msvcr110.dll丢失的解决方法有哪些-常见方法教程

我们在日常使用电脑中经常遇到各种问题,比如系统文件丢失是最常见的,其中msvcr110.dll丢失也是非常常见的问题,那么msvcr110.dll文件为什么会丢失,丢失对电脑有什么影响呢,丢失了有什么解决方法?今天小编就…

Synchronized 优化

目录 前言 重点 一、 轻量级锁 二、锁膨胀 三、重量锁 四、偏向锁 五、其他优化 我的其他博客 前言 Java synchronized 是一种机制,可以保证多个线程在访问共享资源时的同步性。synchronized 关键字可以用于方法或代码块上,当一个线程获取了这个对…

【动态规划】03斐波那契数列模型_最小花费爬楼梯_C++(easy1)

题目链接:leetcode使用最小花费爬楼梯 目录 题目解析: 算法原理 1.状态表示 2.状态转移方程 3.初始化 4.填表顺序 5.返回值 编写代码 题目解析: 题目让我们求达到楼梯顶部的最低花费. 由题可得: cost[i] 是从楼梯第 i 个…

第6章:知识建模:概述、方法、实例

💗💗💗欢迎来到我的博客,你将找到有关如何使用技术解决问题的文章,也会找到某个技术的学习路线。无论你是何种职业,我都希望我的博客对你有所帮助。最后不要忘记订阅我的博客以获取最新文章,也欢…

java--LinkedHashSet集合的底层原理和TreeSet集合

1.LinkedHashSet底层原理 ①依然是基于哈希表(数组、链表、红黑树)实现的 ②但是,它的每个元素都额外的多了一个双链表的机制记录它前后元素的位置。 2.TreeSet ①特点:不重复、无索引、可排序(默认升序排序,按照元素的大小,由…

Nacos热更新(动态获取配置)

写在前面:各位看到此博客的小伙伴,如有不对的地方请及时通过私信我或者评论此博客的方式指出,以免误人子弟。多谢!如果我的博客对你有帮助,欢迎进行评论✏️✏️、点赞👍👍、收藏⭐️⭐️&#…

el-date-picker 限制选择范围最大为一年,设置快捷选项,设置默认时间

el-date-picker 限制选择范围最大为一年&#xff1a; 主要代码为&#xff1a;:picker-options"pickerOptions" 以及 blur"pickerBlur" <el-date-pickerv-model"transactionTime"type"daterange"style"width: 200px"size…

盒马补贴量价-2021KDD

概述&#xff1a; 电商商品定价三个关键问题&#xff1a; 在只有观测数据的时候&#xff0c;怎么构建价格弹性&#xff0c;现在来看这就是一个反事实推断的问题&#xff0c;不仅是如何做的问题&#xff0c;还有如何评估的问题。长周期的规划决策问题怎么建模 & 求解&#…

从零开始学UniApp微信小程序开发:头部适配技巧让你事半功倍!

在 UniApp 中&#xff0c;在微信小程序开发中&#xff0c;头部适配可以通过修改 pages.json 中的 navigationStyle 配置项来实现&#xff0c;具体操作步骤如下&#xff1a; 1.进入 pages.json 文件 在 UniApp 项目的根目录中找到 pages.json 文件&#xff0c;打开该文件。 2…

Win11专业版,eNSP启动失败,错误代码40 解决方法

微软Win11系统默认开启的 Virtualization-based Security &#xff08;VBS&#xff09;“基于虚拟化的安全性”会导致游戏、跑分性能下降。VBS 基于虚拟化的安全性&#xff0c;通常称为内核隔离。使用硬件虚拟化在内存中创建安全区域&#xff0c;为其他安全功能提供了一个安全平…

Appilied energy论文复现:含多类型充电桩的电动汽车充电站优化配置方法程序代码!

本程序参考Applied energy论文《Optimal planning of electric vehicle charging stations comprising multi-types of charging facilities》&#xff0c;文中主要对多类型充电桩的电动汽车充电站进行优化配置&#xff0c;程序较为简单和基础&#xff0c;具有较强的可扩展性和…

adb命令学习记录

1、 adb ( android debug bridge)安卓调试桥&#xff0c;用于完成电脑和手机之间的通信控制。 xcode来完成对于ios设备的操控&#xff0c;前提是有个mac电脑。 安卓系统是基于linux内核来进行开发的。 2、adb的安装: 本身 adb是 android SDK 其中自带的工具&#xff0c;用于完…

排坑指南之STM32串口接收队列定时异常导致接收失败

背景: 公司的项目,今天讲的这部分功能主要是和IC卡读取板进行串口通讯,然后将读取回来的IC卡保存在本地。我在调试的过程中发现了一个问题,上电刚开始的阶段,程序是好用的,能读取回来IC卡卡号,然后运行一段时间之后,就读取不回来卡号了,刷卡没有响应。 摘要: 讲述STM…

C语言--每日练习题--Day38

第一题 1. 下列代码的运行结果&#xff08;&#xff09; short i 65537; int j i 1; printf("i%d,j%d\n", i, j); A&#xff1a;i 65537&#xff0c;j 65538 B&#xff1a;i 1&#xff0c;j 2 C&#xff1a;i -1&#xff0c;j 0 D&#xff1a;i 1&#xff…

【基础知识】大数据概述

关键词—分布式 化整为零&#xff0c;再化零为整 大数据的定义 传统数据库处理起来困难的数据集。 发展历程 中国开源生态图谱2023 参考内容 中国开源生态图谱 2023.pdf 技术组件说明 数据集成 sqoop、dataX、flume 数据存储 hdfs、kafka 数据处理 mapreduce、hive…

C++学习笔记(十一)------has_a和use_a关系

文章目录 前言 一、has_a关系 1.1 has_a概念 1.2 has_a中构造和析构的顺序 1.3 has_a对象的内存情况 二、use_a关系&#xff08;友元关系&#xff09; 1.友元函数&#xff1a; 2.友元类 3 使用多文件编程的方式重新编辑上述代码 总结 前言 随着技术的革新&#xff0c;出现各种各…

通俗易懂,什么是.NET Core以及.NET Core能做什么

我们都知道.NET Core是一个可以用来构建现代、可伸缩和高性能的跨平台软件应用程序的通用开发框架。可用于为Windows、Linux和MacOS构建软件应用程序。与其他软件框架不同&#xff0c;.NET Core是最通用的框架&#xff0c;可用于构建各种软件&#xff0c;包括Web应用程序、移动…

搭建商城系统的构架如何选择?

近期有很多网友在csdn、gitee、知乎的评论区留言&#xff0c;搭建商城系统是选择单体架构还是微服务架构&#xff0c;这里先说结论&#xff0c;如果是纯电商的话&#xff0c;商城系统的架构建议选择单体架构。我们分析下微服务和单体架构的优劣势&#xff0c;就知道了。 一、什…

网易有道强力开源中英双语语音克隆

项目地址&#xff08;基于PromptTTS&#xff09;&#xff1a; https://github.com/netease-youdao/EmotiVoice EmotiVoice Docker镜像 尝试EmotiVoice最简单的方法是运行docker镜像。你需要一台带有NVidia GPU的机器。先按照Linux和Windows WSL2平台的说明安装NVidia容器工具…

ECCV 2024 European Conference on Computer Vision

目录 DatesPeople 官网&#xff1a; https://eccv2024.ecva.net/ 链接 Dates Thursday, February 29, 2024 authors Abstract registration deadlineThursday, March 7, 2024 authors Submission deadlineThursday, March 14, 2024 authors Supplementary materials deadlineM…