数据结构之跳表

本文介绍了跳表的概念,它是通过在链表中添加多层索引提高查找效率,查询时间复杂度为O(logn),空间复杂度因索引设置不同而为O(n)或减半。重点讲解了插入和删除操作的原理及其实现,以及如何防止索引退化。
摘要由CSDN通过智能技术生成

数据结构之跳表

跳表可以说是B+树的一种拓展

1. 什么是跳表

在介绍跳表的定义之前,我们先来了解一下链表,对于一个单链表来说,即便链表中存储的数据是有序的,如果我们要想在七种查找某个数据,只能从头到尾遍历链表,查找的效率很低,查找的时间复杂度为 O(n);
在这里插入图片描述

由于单链表的查找效率太慢,我们想,可以通过什么方式能够提高链表的查找效率呢?

我们试着对链表中建立索引,使用索引来标记和记录数据的位置。如下图

在这里插入图片描述

如上图所示,我们给单链表建立了一个索引层,当我们想查找某个数据(16)时,我们可以先在索引层遍历,当遍历到索引层中值为13,我们发现下一个节点是17,那么我们要查找的节点16必定在这两个索引之间,此时,我们可以通过down指针下降到单链表这一层,继续遍历,我们很快就能查找到我们所需要的节点。

无索引方式需要遍历 10 个结点

有索引的方式需要遍历 7个结点

可以看出,我们通过增加一层索引层的方式,能够有效的减少链表查找数据时,遍历的次数。也就是查找的效率增高了。(空间换时间)

既然我们能够通过添加索引的方式,提高链表查找数据的效率,那么我们是否能够通过建立多层索引的方式,提升更多的查找效率呢?
在这里插入图片描述

可以看出,当我们建立二层索引时,查找16时,需要遍历的次数更少了。遍历6次

当链表的长度n比较大时,在构建索引之后,查找效率的提升就会非常明显。

如果,这种链表加多层索引的结构,就是跳表

2. 跳表查询时间复杂度

跳表中数据查询的时间复杂度为 logn

3. 跳表的空间复杂度

我们分别通过索引点的数量来比较空间的占用量

  1. 每2个节点抽一个作为索引
    在这里插入图片描述

​ 通过等比数列计算公式得知:索引的结点综合为 n/2+n/4+n/8…+8+4+2=n-2。所以跳表的空间复杂度为 O(n);

  1. 每3个节点抽一个作为索引

    在这里插入图片描述

​ 通过等比数列求和公式,总的索引结点大约就是 n/3+n/9+n/27+…+9+3+1=n/2。尽管

空间复杂度还是 O(n),但比上面的每两个结点抽一个结点的索引构建方法,要减少了一半

的索引结点存储空间

4. 跳表高效的动态插入和删除

跳表数据插入和删除的时间复杂度为 O(logn)

4.1 跳表的插入操作

我们知道,在单链表中,如何我们清楚的知道数据插入的具体位置,单链表的插入复杂度为O(1)。当我们无法确定插入位置时,我们需要先遍历链表(查找操作),找到对应的位置,然后再执行插入操作,时间 复杂度为 O(n)。

同理,我们在跳表中执行插入操作的时间复杂度为 O(logn)。因为我们需要先通过查找(上面我们已经分析过,跳表的查找时间复杂度为O(logn))找到数据插入的位置。

在这里插入图片描述

当我们不停的往跳表中插入数据时,如果我们不更新索引,就会出现某两个索引节点间数据特多的情况,极端情况下,出现跳表退化成单链表的情况。(如果链表中结点多了,索引结点就相应地增加一些,避免复杂度退化,随机索引的方式添加索引节点的数量)

当插入一条数据时,我们通过一个随机函数,来决定将这个结点插入到哪几级索引中,比如随机函数生成了值 K,那我们就将这个结点添加到第一级到第 K 级这 K 级索引中。

4.2 跳表的删除操作

跳表中删除的两种情况:

  1. 待删除的节点不在索引中
  2. 待删除的节点在索引中
4.2.1 待删除的节点不在索引中

直接删除

4.2.2 待删除的节点在索引中

当待删除的节点在索引中时,我们除了要删除原始链表中的节点,还需要删除索引中的节点

单链表删除时,我们需要通过遍历拿到删除节点的前驱节点;

双向链表删除时,就不需要考虑遍历的问题了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

王叮咚

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值