当前位置: 首页 > article >正文

什么是跳表?(Skip List)

跳表(Skip List)完整讲解

跳表是一种基于链表的有序数据结构,通过多层索引提高查找速度。它的核心思想是:“用多个层级的索引来加速查找”,从而达到类似二分查找的效果,同时保留链表的动态性。


1. 跳表的基本概念

跳表的结构类似于一个多层高速公路

  • 底层(Level 0)是一个 有序链表,存储所有元素。
  • 上层索引(Level 1、2、3…)是一些“跳跃”节点,帮助快速定位元素,就像高速公路上的“快速通道”。
  • 层数越高,跳过的元素越多,查找效率越快。

示例: 假设有一组有序数据 {1, 2, 3, 4, 5, 6, 7, 8, 9, 10},如果直接用链表存储,查找 9 需要走 9 步

1 → 2 → 3 → 4 → 5 → 6 → 7 → 8 → 9 → 10

如果用跳表,有多个索引层:

Level 2:  1 ------------- 5 ------------- 9
Level 1:  1 ---- 3 ---- 5 ---- 7 ---- 9 ---- 10
Level 0:  1 → 2 → 3 → 4 → 5 → 6 → 7 → 8 → 9 → 10

🔹 查找 9

  1. Level 2 开始:1 → 5 → 9只走 2 步
  2. 如果没找到,再往下到 Level 1Level 0

结论: ✅ 跳表比单链表快很多,查找 O(log n),而普通链表是 O(n)


2. 跳表的时间复杂度

操作平均时间复杂度最坏情况
查询O(log n)O(n)(如果跳表退化成链表)
插入O(log n)O(n)
删除O(log n)O(n)

为什么是 O(log n)

  • 跳表的每层跳过一半的元素,类似二分查找
  • 如果有 n 个元素,总共大约有 log n 层,每次查找最多经过 log n 步。

最坏情况:

  • 如果随机化索引层失败,跳表可能会退化成普通链表,最坏情况下查找变成 O(n)
  • 但概率极低,通常不会发生。

3. 跳表的空间复杂度

  • 空间复杂度:O(n) ~ O(n log n)(具体取决于索引层的个数)
  • 每个元素会随机出现在多个索引层,但大部分只在底层,整体空间消耗比平衡树略高,但比完全索引(如 B+ 树)低。

4. 跳表的操作

(1)数据查询

🔹 步骤:

  1. 从最高索引层开始,查找接近目标值的节点。
  2. 如果该层的当前节点值 >= target,则往下移动一层。
  3. 底层链表(Level 0) 找到目标节点。

🔹 示例:查找 7

Level 2:  1 ------------- 5 ------------- 9
Level 1:  1 ---- 3 ---- 5 ---- 7 ---- 9 ---- 10
Level 0:  1 → 2 → 3 → 4 → 5 → 6 → 7 → 8 → 9 → 10
  1. Level 2 开始:1 → 5,发现 9 太大,回退到 5,然后下到 Level 1
  2. Level 15 → 7,找到了 7只走 2 步

查询时间复杂度 O(log n)


(2)数据插入

🔹 步骤:

  1. 从最高层往下找到要插入的位置。
  2. 随机生成层数(50% 概率晋升到下一层)。
  3. 插入新节点,并调整指针

🔹 示例:插入 6

  1. 查找插入位置(在 57 之间)。
  2. 随机生成层数(假设 6 出现在 Level 0 和 Level 1)。
  3. 插入 6 并更新指针
Level 1:  1 ---- 3 ---- 5 ---- 6 ---- 7 ---- 9 ---- 10
Level 0:  1 → 2 → 3 → 4 → 5 → 6 → 7 → 8 → 9 → 10

插入时间复杂度 O(log n)


(3)数据删除

🔹 步骤:

  1. 从最高层向下查找目标节点。
  2. 删除该节点,并更新前后指针
  3. 如果某一层的索引为空,则删除该层

删除时间复杂度 O(log n)


5. Redis 为什么使用跳表?

Redis 的有序集合(ZSet)*支持*快速插入、删除、范围查询,需要一个高效的有序数据结构**。

🔹 跳表 vs. 红黑树

对比项跳表(Skip List)红黑树(Red-Black Tree)
查找O(log n)O(log n)
插入O(log n)O(log n)
删除O(log n)O(log n)
范围查询快(链表结构遍历)较慢(树结构遍历)
实现难度简单复杂(旋转、调整)
插入/删除成本只改指针涉及旋转
空间占用稍高更紧凑

🔹 Redis 选择跳表的原因

  1. 范围查询更快(链表可直接遍历)。
  2. 代码更简单(比红黑树易实现)。
  3. 插入、删除操作不会有额外的平衡成本(红黑树需要旋转)。

跳表更适合 Redis 的场景,所以 Redis 有序集合(ZSet) 使用跳表 + 哈希表实现。


6. 其他工业级应用

  • 数据库索引(LevelDB、RocksDB):跳表可以用于存储引擎的索引,比 B+ 树更适合 LSM 树(Log-Structured Merge Tree)。
  • 搜索引擎(Elasticsearch):用于倒排索引的存储结构。
  • 分布式存储(BigTable):Google BigTable 采用跳表 + SSTable 结构。

7. 结论

  • 跳表是“多层索引的有序链表”,查询、插入、删除都是 O(log n)
  • Redis 选择跳表而不是红黑树,因为跳表的范围查询更快、实现更简单
  • 跳表适用于高效的排序存储和索引结构,被广泛用于数据库、搜索引擎、缓存系统。

http://www.kler.cn/a/595275.html

相关文章:

  • cippe2025北京石油展,遨游通讯将携多款防爆手机亮相!
  • Java高并发容器的内核解析:从无锁算法到分段锁的架构演进
  • 移动WEB开发之rem适配布局
  • 搭建主从DNS、nfs、nginx
  • 36、deque分配器的作用
  • Qt 基本使用方法介绍
  • 从零开始学2PC:分布式事务的原子性保障
  • C++编译流程
  • UNIX网络编程笔记:一些网络协议的相关知识
  • 【Android】基础架构(详细介绍)
  • WordPress 性能优化技术指南:打造快速加载的网站
  • 【python】OpenCV—Hand Landmarks Detection
  • 能源监控软件UI界面设计:平衡功能性与审美性的艺术
  • 针对耳鸣患者推荐的一些菜谱和食材
  • 透析Vue的nextTick原理
  • uniapp小程序,输入框限制输入(正整数、小数后几位)
  • Umi-OCR 实践教程:离线、免费、高效的图像文字识别工具
  • 家庭网络安全:智能设备与IoT防护——当“智能家居”变成“僵尸网络”
  • Java 记忆链表,LinkedList 的升级版
  • PostgreSQL_数据表结构设计并创建