数据结构与算法--跳表

什么是跳表

如果一个单链表,储存数据是有序的,我们要查找一个数据,需要遍历一遍链表,时间复杂度为O(n),效率不是很高
在这里插入图片描述
那么该如何提高效率呢?如果我们像下图一样对链表建立一层索引,查找起来会不会快一些,每俩个结点提取一个结点到上一级,我们把抽出来的一层叫做索引层,down代表down指针,指向下一级
在这里插入图片描述
比如我们要查找16,我们可以先在索引层查找,当查到13,下一个是17大于16,那么就向下查找,这个时候我们只需要遍历俩个就可以找到,原来需要遍历10个结点才可以找到,先在只需要遍历7个结点就可以

看来加了一层索引后效率确实提高了,如果我么你多加基层索引,效率会不会更高?
我们在第一层索引之上,每俩个结点抽出一个索引,再建立一层索引,再次查找16,只需要遍历6个结点就行了
在这里插入图片描述
这种链表加多级索引的结构,就是跳表

跳表的时间复杂度

一个链表查找的时间复杂度为O(n),那么跳表的时间复杂度是多少呢

假如链表有n个数据,会有多少层索引?

跟上面一样,我们每俩个结点抽取一个结点,那么第一层索引结点数是n/2,第二层结点数就是n/4,第三层索引数就是n/8,以此类推,第K层索引结点数就是n/(2k)

假如索引有h级,最高索引有2个结点,代入公式,n/2h=2, h=log2n-1,如果包含原始链表一层,那么跳表的高度为log2n,我们在跳表中查询某个数据的时候,每层需要表里m个结点,那么在跳表查询一个数据的时间复杂度是O(m*logn)

那么m是多少呢?
假设我们需要查找的数据x,在K级索引中,我们遍历到y发现x>y,并且x<z,我们通过down指针向下一层查找,而下一层x–z之间只有3个数据,以此类推,每一级索引都需要遍历3个,所以m=3
在这里插入图片描述
所以跳表的时间复杂度就是O(logn),这种效率的提升,前提是建立了索引,也就是空间换时间

跳表的空间复杂度

假设链表有n个数据,那么第一层索引n/2个结点,第二层n/4一次类推
在这里插入图片描述
n/2+n/4+n/8+…+8+4+2=n-2,空间复杂度为O(n)

这个是每俩个结点抽取一个,如果每3个结点抽取一个呢
在这里插入图片描述
n/3+n/9+n/27…+9+3+1=n/2,虽然空间复杂度还是O(n),但是减少了一半的空间

跳表高效的插入和删除

我们知道,在链表中插入数据时间复杂度伪O(1),只不过需要查找到插入的位置,单链表查询需要O(n),所以链表插入时间复杂度O(n),但是跳表查找的时间复杂度为O(logn),所以跳表的插入是将复杂度为O(logn),删除也一样时间复杂度为O(logn),不过除了删除链表中的节点,还需要的删除索引中的节点

跳表索引的动态更新

如果我们不停的向调表中加入数据,不更新索引,就有可能造成俩个索引之间的数据特别多,极端下还可能退化成单链表
在这里插入图片描述
我们需要一种手段,去维护索引和原始链表之间的平衡,如果链表中的节点多了,就适当添加一些索引,避免复杂度退化

在向跳表添加数据时,我们通过一个随机函数来决定结点插入到那几级的索引中
在这里插入图片描述

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值