数据结构-跳表

跳表(skip list)

增删改查时间复杂度都是 O(logn)

  • 查询时间复杂度:就是跳表的高度 O(logn)
  • 增删改时间复杂度:
    先查询到目标节点,然后对其增删改,复杂度=查询+增删改
    因为是链表,增删改的时间复杂度为常数级别,所有最终增删改总的时间复杂度就是查询的时间复杂度,也就是 O(logn)

空间复杂度:O(n)

使用场景:
适合查询多,增删改少的场景,因为增删改需要修改索引
具体用到跳表的地方:
redis的zset数据结构
查询引擎:ElasticSearch
noSQL数据库HBase 、Google 开源的 key/value 存储引擎 LevelDB

设计原理:
给链表加索引,比如下面的例子中,每两个节点取一个索引
第一层索引:1、4、7、9、13、17、
第二层索引:1、7、13、

查询时就从最上面一层索引开始往下查找,比如查找的是5,比1大接着和7比,比7小则往下。
和4比,比4大比7小接着往下,最后找打5.
在这里插入图片描述

跳表索引动态更新:随机函数

当我们不停地往跳表中插入数据时,如果我们不更新索引,就有可能出现2 个索引结点之间数据非常多的情况。
极端情况下,跳表还会退化成单链表
作为一种动态数据结构,我们需要用随机函数来维护索引与原始链表大小之间的平衡

我们通过一个随机函数,来决定将这个结点插入到哪几级索引中,
比如随机函数生成了值 K,那我们就将这个结点添加到第一级到第 K 级索引中。
如果K=0则不需要为其建索引
在这里插入图片描述

复杂度公式证明

时间复杂度证明

1、跳表的高度 logn
如果链表有n个节点,每2个节点抽取抽出一个节点作为上一级索引的节点,那第1级索引的节点个数大约是 n/2,第2级索引的节点个数大约是 n/4,依次类推,第k级索引的节点个数就是n/(2^ k)。假设索引有h级别,最高级的索引有2个节点,则有n/(2^h)=2,得出h=log2n-1,包含原始链表这一层,整个跳表的高度就是logn

2、查询时间复杂度 O(logn)
假设我们在跳表中查询某个数据的时候,如果每一层都遍历 m 个节点,那在跳表中查询一个数据的时间复杂度就是O(m*logn)

那这个 m 是多少呢?m=3
如下图所示,假设我们要查找的数据是 x,在第 k 级索引中,我们遍历到 y 节点之后,发现 x 大于 y,小于后面的节点 z,所以我们通过 y 的 down 指针,从第k级下降到第 k-1级索引。在第k-1级索引中,y 和 z 之间只有3个节点(包含 y 和 z),所以,我们在k-1级索引中最多只需要遍历3个节点,以此类推,每一级索引都最多只需要遍历3个节点。
所以m=3。因此在跳表中查询某个数据的时间复杂度就是O(logn)
在这里插入图片描述

空间复杂度证明

1、计算索引的节点总数
如果链表有n个节点,每2个节点抽取抽出一个节点作为上一级索引的节点,那每一级索引的节点数分别为:n/2,n/4,n/8,…,8,4,2,等比数列求和 n-1,所以跳表的空间复杂度为O(n)

2、 如何优化空间复杂度
如果链表有n个节点,每3或5个节点抽取抽出一个节点作为上一级索引的节点,那每一级索引的节点数分别为(以3为例):n/3,n/9,n/27,…,27,9,3,1,等比数列求和 n/2,所以跳表的空间复杂度为O(n),和每2个节点抽取一次相比,时间复杂度要低不少。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值