高效的跳表

2024-02-02 12:44
文章标签 高效 跳表

本文主要是介绍高效的跳表,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

高效的跳表

  • 一、 概念
  • 二、 实现原理
  • 三、存在的问题
  • 四、解决方法
  • 五、如何保证效率
  • 六、代码实现
  • 七、总结
    • 对比平衡搜索树
    • 对比哈希表

一、 概念

跳表,是一种用来查询数据的数据结构,它是由William Pugh发明的,借助有序链表,来实现高效地查询

二、 实现原理

William Pugh的优化思路是,每相邻两个节点升高一层,增加一个指针,让指针指向下下个节点,依次类推,形成下图的c,每一层都能排除一半,类似于二分查找,时间复杂度为O(log n)
在这里插入图片描述

三、存在的问题

插入删除数据时,就会打乱上下相邻两层链表上节点个数严格的2:1的对应关系,而要维持这种对应关系,就必须把新插入的节点及其后面的所有节点重新进行调整,但这会让时间复制度退化为O(n)

四、解决方法

William Pugh为了解决这个问题,做了一个大胆的处理,不再严格要求这种对应比例关系,而是插入一个节点的时候,随机出一个层数,这样每次插入和删除都不再需要考虑其它节点的层数,实现起来也就简单多了
在这里插入图片描述

五、如何保证效率

一般跳表会设计一个最大层数maxLevel的限制,其次,会设置一个多增加一层的概率p,伪代码如下图
在这里插入图片描述
在Redis的skiplist实现中,p取1/4,maxLevel取32,根据前面的伪代码,定量分析如下图
在这里插入图片描述
一个节点的平均层数,计算如下图
在这里插入图片描述

六、代码实现

首先,得定义一个节点结构体,一个节点由值和它的层数(下一个结点指针的集合)组成
在这里插入图片描述
跳表,则有三个成员,_head是一个哨兵节点,概率p和最大层数maxLevel给缺省值即可,同时,构造函数内,还需给一个随机数种子,后面用来获取节点层数
在这里插入图片描述
在这里插入图片描述
查找某个值,从上往下开始找,让当前节点指针指向哨兵节点,判断它的下一个节点值和目标值的大小关系,下一个节点值为空或比目标值大,就往下走,即层数下标-1;如果比目标值小,就往右走;否则,则表明找到了,直接返回true即可,如果层数下标都小于0了,就返回false,表明没有找到
在这里插入图片描述
类似于单链表,跳表要插入一个节点或删除一个节点,就必须找到目标节点的前一个节点的集合,这样才能插入或者删除节点,例如,插入20,它的前一个节点集合,自上而下为_head,17,19,如下图
在这里插入图片描述
代码类似于查找目标值,不再赘述
在这里插入图片描述
获取节点层数
在这里插入图片描述

插入节点,首先,获取它的前一个节点的集合,其次,获取节点的层数,同时,需要保证_head节点的层数始终是所有节点中最多的,然后就是链表的插入操作了
在这里插入图片描述
删除节点,首先,得判断节点在不在,不在,就不需要删除了,直接返回即可,删除操作也就是链表的删除操作,最后,做一个层数更新,因为删除节点后,头节点的层数可能会有很多是不必要的,影响查找效率,所以做了一个小的优化
在这里插入图片描述
下面的一个leetcode题目,可以用来验证写的对不对
跳表

七、总结

对比平衡搜索树

对比AVL树和红黑树,都可以做到遍历数据有序,时间复杂度也差不多,而跳表的优势在于:

实现简单,容易控制,而平衡树增删改查都更复杂

跳表的额外空间消耗更低,平衡树节点需要存储三个节点指针,父亲和左右孩子,还有平衡因子或颜色等消耗

对比哈希表

相对于哈希表,优势小了很多,首先,哈希表查找数据的时间复杂度为O(1),比跳表快,跳表的优势在于:

遍历数据有序

跳表的空间消耗略小一些,哈希表存在链接指针和表空间消耗

哈希表扩容有性能损耗

哈希表在极端场景下,哈希冲突高,效率下降厉害,需要红黑树来弥补

这篇关于高效的跳表的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/670747

相关文章

使用Python实现高效的端口扫描器

《使用Python实现高效的端口扫描器》在网络安全领域,端口扫描是一项基本而重要的技能,通过端口扫描,可以发现目标主机上开放的服务和端口,这对于安全评估、渗透测试等有着不可忽视的作用,本文将介绍如何使... 目录1. 端口扫描的基本原理2. 使用python实现端口扫描2.1 安装必要的库2.2 编写端口扫

Oracle查询优化之高效实现仅查询前10条记录的方法与实践

《Oracle查询优化之高效实现仅查询前10条记录的方法与实践》:本文主要介绍Oracle查询优化之高效实现仅查询前10条记录的相关资料,包括使用ROWNUM、ROW_NUMBER()函数、FET... 目录1. 使用 ROWNUM 查询2. 使用 ROW_NUMBER() 函数3. 使用 FETCH FI

在C#中获取端口号与系统信息的高效实践

《在C#中获取端口号与系统信息的高效实践》在现代软件开发中,尤其是系统管理、运维、监控和性能优化等场景中,了解计算机硬件和网络的状态至关重要,C#作为一种广泛应用的编程语言,提供了丰富的API来帮助开... 目录引言1. 获取端口号信息1.1 获取活动的 TCP 和 UDP 连接说明:应用场景:2. 获取硬

Python实现高效地读写大型文件

《Python实现高效地读写大型文件》Python如何读写的是大型文件,有没有什么方法来提高效率呢,这篇文章就来和大家聊聊如何在Python中高效地读写大型文件,需要的可以了解下... 目录一、逐行读取大型文件二、分块读取大型文件三、使用 mmap 模块进行内存映射文件操作(适用于大文件)四、使用 pand

高效管理你的Linux系统: Debian操作系统常用命令指南

《高效管理你的Linux系统:Debian操作系统常用命令指南》在Debian操作系统中,了解和掌握常用命令对于提高工作效率和系统管理至关重要,本文将详细介绍Debian的常用命令,帮助读者更好地使... Debian是一个流行的linux发行版,它以其稳定性、强大的软件包管理和丰富的社区资源而闻名。在使用

高效+灵活,万博智云全球发布AWS无代理跨云容灾方案!

摘要 近日,万博智云推出了基于AWS的无代理跨云容灾解决方案,并与拉丁美洲,中东,亚洲的合作伙伴面向全球开展了联合发布。这一方案以AWS应用环境为基础,将HyperBDR平台的高效、灵活和成本效益优势与无代理功能相结合,为全球企业带来实现了更便捷、经济的数据保护。 一、全球联合发布 9月2日,万博智云CEO Michael Wong在线上平台发布AWS无代理跨云容灾解决方案的阐述视频,介绍了

嵌入式QT开发:构建高效智能的嵌入式系统

摘要: 本文深入探讨了嵌入式 QT 相关的各个方面。从 QT 框架的基础架构和核心概念出发,详细阐述了其在嵌入式环境中的优势与特点。文中分析了嵌入式 QT 的开发环境搭建过程,包括交叉编译工具链的配置等关键步骤。进一步探讨了嵌入式 QT 的界面设计与开发,涵盖了从基本控件的使用到复杂界面布局的构建。同时也深入研究了信号与槽机制在嵌入式系统中的应用,以及嵌入式 QT 与硬件设备的交互,包括输入输出设

高效录音转文字:2024年四大工具精选!

在快节奏的工作生活中,能够快速将录音转换成文字是一项非常实用的能力。特别是在需要记录会议纪要、讲座内容或者是采访素材的时候,一款优秀的在线录音转文字工具能派上大用场。以下推荐几个好用的录音转文字工具! 365在线转文字 直达链接:https://www.pdf365.cn/ 365在线转文字是一款提供在线录音转文字服务的工具,它以其高效、便捷的特点受到用户的青睐。用户无需下载安装任何软件,只

【C++高阶】C++类型转换全攻略:深入理解并高效应用

📝个人主页🌹:Eternity._ ⏩收录专栏⏪:C++ “ 登神长阶 ” 🤡往期回顾🤡:C++ 智能指针 🌹🌹期待您的关注 🌹🌹 ❀C++的类型转换 📒1. C语言中的类型转换📚2. C++强制类型转换⛰️static_cast🌞reinterpret_cast⭐const_cast🍁dynamic_cast 📜3. C++强制类型转换的原因📝

基于 YOLOv5 的积水检测系统:打造高效智能的智慧城市应用

在城市发展中,积水问题日益严重,特别是在大雨过后,积水往往会影响交通甚至威胁人们的安全。通过现代计算机视觉技术,我们能够智能化地检测和识别积水区域,减少潜在危险。本文将介绍如何使用 YOLOv5 和 PyQt5 搭建一个积水检测系统,结合深度学习和直观的图形界面,为用户提供高效的解决方案。 源码地址: PyQt5+YoloV5 实现积水检测系统 预览: 项目背景