算法通关村番外篇-跳表

这篇具有很好参考价值的文章主要介绍了算法通关村番外篇-跳表。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

大家好我是苏麟 , 今天来聊聊调表 .

跳表很少很少实现所以我们只了解就可以了 . 

跳表

链表在查找元素的时候,因为需要逐一查找,所以查询效率非常低,时间复杂度是O(N),于是就出现了跳表。跳表是在链表基础上改进过来的,实现了一种「多层」的有序链表,这样的好处是能快读定位数据。

那跳表长什么样呢?我这里举个例子,下图展示了一个层级为 3 的跳表。

算法通关村番外篇-跳表,算法村,算法,java,数据结构

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

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

如果我们要在链表中查找节点 4 这个元素,只能从头开始遍历链表,需要查找 4 次,而使用了跳表后,只需要查找 2 次就能定位到节点 4,因为可以在头节点直接从 L2 层级跳到节点 3,然后再往前遍历找到节点 4。

可以看到,这个查找过程就是在多个层级上跳来跳去,最后定位到元素。当数据量很大时,跳表的查找复杂度就是 O(logN)。

跳表节点层数设置

跳表的相邻两层的节点数量的比例会影响跳表的查询性能。

举个例子,下图的跳表,第二层的节点数量只有 1 个,而第一层的节点数量有 6 个。

算法通关村番外篇-跳表,算法村,算法,java,数据结构

这时,如果想要查询节点 6,那基本就跟链表的查询复杂度一样,就需要在第一层的节点中依次顺序查找,复杂度就是 O(N) 了。所以,为了降低查询复杂度,我们就需要维持相邻层结点数间的关系。

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

下图的跳表就是,相邻两层的节点数量的比例是 2 : 1。

算法通关村番外篇-跳表,算法村,算法,java,数据结构

那怎样才能维持相邻两层的节点数量的比例为 2 : 1 呢?

如果采用新增节点或者删除节点时,来调整跳表节点以维持比例的方法的话,会带来额外的开销。

Redis 则采用一种巧妙的方法是,跳表在创建节点的时候,随机生成每个节点的层数,并没有严格维持相邻两层的节点数量比例为 2 : 1 的情况。

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

这样的做法,相当于每增加一层的概率不超过 25%,层数越高,概率越低,层高最大限制是 64。

虽然我前面讲解跳表的时候,图中的跳表的「头节点」都是 3 层高,但是其实如果层高最大限制是 64,那么在创建跳表「头节点」的时候,就会直接创建 64 层高的头节点

跳表的插入与删除

假设我们要插入的节点是10,首先找到待插节点的前置节点(仅小于待插入节点):

算法通关村番外篇-跳表,算法村,算法,java,数据结构

接下来,按照一般链表的插入方式,把节点10插到节点9的下一个 位置:

算法通关村番外篇-跳表,算法村,算法,java,数据结构

这样是不是插入工作就完成了呢?并不是。随着原始链表的新节 点越来越多,索引会渐渐变得不够用了,因此索引节点也需要相应做 出调整

如何调整索引呢?我们让新插入的节点随机“晋升”,也就是成 为索引节点。新节点晋升成功的几率是50%。

假设第一次随机的结果是晋升成功,那么我们把节点10作为索引 节点,插到第1层索引的对应位置,并且向下指向原始链表的节点10:

算法通关村番外篇-跳表,算法村,算法,java,数据结构

新节点在成功晋升之后,仍然有机会继续向上一层索引晋升。我 们再进行一次随机,假设随机的结果是晋升失败,那么插入操作就告 一段落了。

新节点10已经晋升到 第2层索引,下一次随机的结果仍然是晋升成功,这时候我们该怎么 办?

算法通关村番外篇-跳表,算法村,算法,java,数据结构

这时候,我们直接让索引增加一层,就像下面这样:

算法通关村番外篇-跳表,算法村,算法,java,数据结构

至于跳表删除节点的过程,则是相反的思路。

假设我们要从跳表中删除节点10,首先按照跳表查找节点的方 法,找到待删除的节点:

算法通关村番外篇-跳表,算法村,算法,java,数据结构

接下来,按照一般链表的删除方式,把节点10从原始链表当中删 除:

算法通关村番外篇-跳表,算法村,算法,java,数据结构

这样是不是删除工作就完成了呢?并不是。我们需要顺藤摸瓜, 把索引当中的对应节点也一一删除:

算法通关村番外篇-跳表,算法村,算法,java,数据结构

那么,如果某一层索引的节点被删光了,该怎么办呢?

很好解决,直接把没有节点的那一层删去就好了。

在刚才的例子当中,第3层索引的节点已经没有了,因此我们把整 个第3层删去:

算法通关村番外篇-跳表,算法村,算法,java,数据结构

最终的删除结果如下:

算法通关村番外篇-跳表,算法村,算法,java,数据结构


这期就到这里 , 下期见!文章来源地址https://www.toymoban.com/news/detail-790327.html

到了这里,关于算法通关村番外篇-跳表的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【算法&数据结构体系篇class36】有序表 (中篇)SB树、跳表

    1 )让每一个叔叔节点为头的数,节点个数都不少于其任何一个侄子节点 2 )也是从底层被影响节点开始向上做路径每个节点检查 3 )与 AVL 树非常像,也是四种违规类型: LL 、 RR 、 LR 、 RL 4 )与 AVL 树非常像,核心点是: LL (做一次右旋)、 RR (做一次左旋) LR 和 RL (利

    2024年02月03日
    浏览(67)
  • 【flink番外篇】19、Datastream数据类型到Table schema映射示例

    一、Flink 专栏 Flink 专栏系统介绍某一知识点,并辅以具体的示例进行说明。 1、Flink 部署系列 本部分介绍Flink的部署、配置相关基础内容。 2、Flink基础系列 本部分介绍Flink 的基础部分,比如术语、架构、编程模型、编程指南、基本的datastream api用法、四大基石等内容。 3、

    2024年01月21日
    浏览(41)
  • 【flink番外篇】14、Flink异步I/O访问外部数据示例

    一、Flink 专栏 Flink 专栏系统介绍某一知识点,并辅以具体的示例进行说明。 1、Flink 部署系列 本部分介绍Flink的部署、配置相关基础内容。 2、Flink基础系列 本部分介绍Flink 的基础部分,比如术语、架构、编程模型、编程指南、基本的datastream api用法、四大基石等内容。 3、

    2024年01月16日
    浏览(33)
  • 【flink番外篇】9、Flink Table API 支持的操作示例(14)- 时态表的join(java版本)

    一、Flink 专栏 Flink 专栏系统介绍某一知识点,并辅以具体的示例进行说明。 1、Flink 部署系列 本部分介绍Flink的部署、配置相关基础内容。 2、Flink基础系列 本部分介绍Flink 的基础部分,比如术语、架构、编程模型、编程指南、基本的datastream api用法、四大基石等内容。 3、

    2024年02月02日
    浏览(42)
  • 【flink番外篇】15、Flink维表实战之6种实现方式-维表来源于第三方数据源

    一、Flink 专栏 Flink 专栏系统介绍某一知识点,并辅以具体的示例进行说明。 1、Flink 部署系列 本部分介绍Flink的部署、配置相关基础内容。 2、Flink基础系列 本部分介绍Flink 的基础部分,比如术语、架构、编程模型、编程指南、基本的datastream api用法、四大基石等内容。 3、

    2024年01月21日
    浏览(54)
  • 【flink番外篇】15、Flink维表实战之6种实现方式-通过Temporal table实现维表数据join

    一、Flink 专栏 Flink 专栏系统介绍某一知识点,并辅以具体的示例进行说明。 1、Flink 部署系列 本部分介绍Flink的部署、配置相关基础内容。 2、Flink基础系列 本部分介绍Flink 的基础部分,比如术语、架构、编程模型、编程指南、基本的datastream api用法、四大基石等内容。 3、

    2024年01月20日
    浏览(38)
  • 第九章 番外篇:TORCHSCRIPT

    下文中的代码都使用参考教程中的例子。 会给出一点自己的解释。 参考教程: mixing-scripting-and-tracing script and optimize for mobile recipe https://pytorch.org/docs/stable/jit.html OPTIMIZING VISION TRANSFORMER MODEL FOR DEPLOYMEN 我们训练好并保存的pytorch,支持在python语言下的使用,但是不支持在一些

    2024年02月10日
    浏览(28)
  • 数据结构---跳表

    在前面的学习过程中我们学习过链表这个容器,这个容器在头部和尾部插入数据的时间复杂度为O(1),但是该容器存在一个缺陷就是不管数据是否有序查找数据是否存在的时间复杂度都是O(N),我们只能通过暴力循环的方式查找数据是否存在,尽管数据是有序的我们也不能通过二

    2024年02月13日
    浏览(24)
  • 数据结构:跳表讲解

    1.1简介 skiplist本质上也是一种 查找结构 ,用于解决算法中的查找问题,跟 平衡搜索树和哈希表 的价值是一样的,可以 作为key或者key/value的查找模型 。后面我会进行比对。 skiplist是由 William Pugh发明 的,最早出现于他在1990年发表的论文《Skip Lists: A Probabilistic Alternative to Ba

    2024年02月22日
    浏览(30)
  • 【高阶数据结构】跳表

    skiplist本质上也是一种查找结构,用于解决算法中的查找问题,跟平衡搜索树和哈希表的价值是 一样的,可以作为key或者key/value的查找模型。那么相比而言它的优势是什么的呢?这么等我 们学习完它的细节实现,我们再来对比。 skiplist 是由 William Pugh 发明的,最早出现于他在

    2024年02月16日
    浏览(27)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包