跳跃表
跳跃表(Skip List)详解
跳跃表是一种概率型数据结构,用于在有序元素集合中实现高效的查找、插入和删除操作。由 William Pugh 于 1990 年提出,其性能与平衡树(如红黑树)相当,但实现更简单。
核心思想
-
多层链表结构:
- 最底层(L0)包含所有元素的有序链表。
- 每一高层(L1, L2, ...)是低一层的“子集”,通过“跳跃”指针跳过部分节点。
- 高层节点数量呈指数递减(如 L1≈n/2, L2≈n/4)。
-
随机层数:
- 插入节点时,通过随机算法(如抛硬币)决定层数(如 50% 概率进入 L1,25% 进入 L2)。
- 保证高层节点稀疏分布,避免手动平衡。
关键操作
1. 查找(Search)
- 步骤:
- 从最高层头节点开始。
- 向右遍历:若下一节点 ≤ 目标值,则继续右移。
- 若下一节点 > 目标值,则下沉一层。
- 重复直至最底层找到目标或确认不存在。
- 时间复杂度:平均 O(log n),最坏 O(n)。
2. 插入(Insert)
- 步骤:
- 通过查找确定插入位置,并记录每层的前驱节点。
- 随机生成新节点的层高 k。
- 创建新节点,从 L0 到 Lk 依次链接:
- 新节点在 Li 层的后继 = 前驱节点在 Li 层的后继
- 前驱节点在 Li 层的后继 = 新节点
- 示例:插入值 6(随机层数=2)
3. 删除(Delete)
- 步骤:
- 查找目标节点,记录每层的前驱节点。
- 从最高层开始,将前驱节点的指针指向目标节点的后继。
- 移除目标节点,若高层链表为空则降低总层数。
特点与优势
| 特性 | 说明 |
|---|---|
| 时间复杂度 | 查找/插入/删除:平均 O(log n),最坏 O(n)(概率极低) |
| 空间复杂度 | O(n)(每个节点平均指针数 ≈2) |
| 实现难度 | 显著低于平衡树(无需旋转/再平衡) |
| 灵活性 | 天然支持范围查询(如 L0 遍历) |
| 应用场景 | Redis有序集合、LevelDB/RocksDB的MemTable、并发数据结构 |
对比平衡树
| 对比项 | 跳跃表 | 平衡树(如红黑树) |
|---|---|---|
| 实现复杂度 | ✅ 简单(≈100行代码) | ❌ 复杂(需处理旋转/变色) |
| 范围查询 | ✅ 高效(底层链表顺序遍历) | ❌ 需中序遍历 |
| 并发控制 | ✅ 更易实现锁优化 | ❌ 复杂 |
| 确定性 | ❌ 依赖随机算法 | ✅ 严格平衡 |
代码框架(Python 伪代码)
import random
class SkipListNode:
def __init__(self, val, level):
self.val = val
self.next = [None] * level # 每层的后继指针
class SkipList:
def __init__(self, max_level=16, p=0.5):
self.max_level = max_level
self.p = p # 节点晋升概率
self.head = SkipListNode(None, max_level) # 头节点
self.level = 0 # 当前有效层数
def random_level(self):
level = 1
while random.random() < self.p and level < self.max_level:
level += 1
return level
def search(self, target: int) -> bool:
curr = self.head
for i in range(self.level-1, -1, -1): # 从顶层向底层扫描
while curr.next[i] and curr.next[i].val < target:
curr = curr.next[i]
if curr.next[i] and curr.next[i].val == target:
return True
return False
def add(self, num: int) -> None:
update = [self.head] * self.max_level # 记录每层的前驱
curr = self.head
for i in range(self.level-1, -1, -1):
while curr.next[i] and curr.next[i].val < num:
curr = curr.next[i]
update[i] = curr # 保存插入位置的前驱
new_level = self.random_level()
if new_level > self.level:
for i in range(self.level, new_level):
update[i] = self.head
self.level = new_level
new_node = SkipListNode(num, new_level)
for i in range(new_level):
new_node.next[i] = update[i].next[i]
update[i].next[i] = new_node
def erase(self, num: int) -> bool:
update = [None] * self.max_level
curr = self.head
for i in range(self.level-1, -1, -1):
while curr.next[i] and curr.next[i].val < num:
curr = curr.next[i]
update[i] = curr
target = curr.next[0] if curr.next[0] and curr.next[0].val == num else None
if not target:
return False
for i in range(self.level):
if update[i].next[i] != target:
break
update[i].next[i] = target.next[i] # 移除链接
while self.level > 1 and self.head.next[self.level-1] is None:
self.level -= 1 # 降低空层
return True
实际应用
- Redis 有序集合(ZSET):使用跳跃表存储分数排序,支持 O(log n) 的 ZRANGE、ZADD 等操作。
- 数据库引擎:LevelDB/RocksDB 用跳跃表管理内存表(MemTable),加速写入和查询。
- 并发数据结构:通过细粒度锁(如每层加锁)实现高并发访问。
? 核心价值:以接近 O(log n) 的效率实现有序集合操作,同时大幅降低工程复杂度。
变频器调试中跳跃频率和跳跃带宽如何设置?
设置变频器的跳跃频率和带宽,核心目的是 避开负载设备的机械共振点 ,防止设备在特定频率下剧烈振动,从而保护设备并消除噪音。设置时,关键思路是: 精准找到共振点,然后设定一个合适的“禁区”让变频器绕开
2026-07-06 07:06:23
ADS805E测量跳跃幅度很大,不知道是为什么?
我按照手册上直流耦合连接电路,输入是1.5V~3.5V范围,SEL与VREF相连,用430定时器输出转换时钟,结果测量直流时,AD测量结果在几个值之间跳跃,跳跃幅度很大,不知道是为什么,引脚电压控制用3.3V。
基于数据表内容的字段嵌入方法综述
充分利用数据表的丰富信息,影响了查询的准确率。针对数据表内容作为输λ的情况下,如何提升自然语言查询接口的查询准确率的问题,文中创新地提出了基于数据表
资料下载
佚名
2021-05-07 10:52:25
多级注意力跳跃连接网络MLASC-Net
行人属性识别易受视角、尺度和光照等非理想自然条件变化的影响,且某些细粒度属性识别难度较大。为此,提出一种多级注意力跳跃连接网络 MLASC-Net。在网络中间层,利用敏感注意力模块在通道及空间
资料下载
佚名
2021-03-10 16:35:45
开关电源的突发模式和脉冲跳跃模式的原理及区别是什么?
想弄懂开关电源的突发模式和脉冲跳跃模式的原理及区别,以BOOST拓扑为例,希望能够有对应的电感、开关以及输出的波形,谢谢。。
使用M031实现多应用程序跳跃
应用程序: 本示例代码使用 M031 实现多应用程序跳跃, 跳过 IAP 方式 。 BSP 版本: M031 BSP CMSIS V3.03.000 硬件: NuMaker-M031SD V1.1
跳跃表数据结构与算法分析
目前市面上充斥着大量关于跳跃表结构与 Redis 的源码解析,但是经过长期观察后发现大都只是在停留在代码的表面,而没有系统性地介绍跳跃
2023-01-31 13:35:30
未连接时ADC在最大值和最小值之间跳跃怎么办
HI AllMy ADC在未连接时不稳定。当测量终端没有连接时,ADC在显示器上显示一个值,该值在max(32.72)和min(0)之间跳跃;每当我施加电压时,它将显示一个与所施加电压不接近的值
J12电源跳跃器在哪个位置重要吗?
嗨,我最近买了其中的一个,在缺省的PIC166f1619芯片安装的情况下,J12电源跳跃器在哪个位置重要吗?该手册并没有真正说,它是在3.3V位置收到,但我已经注意到,在微芯片分钟视频它在5V位置…
关于用跳跃—扩散模型估算市场隐含价值的分析和介绍
在开发并实现一个跳跃扩散模型参数的估算过程之后,我们使用 MATLAB Live Editor (MATLAB 实时编辑器)将结果作为实时脚本与同事共享。以上流程可以应用于不同资产类别的各种时间序列数据。由于许多金融数据在金融危机时期和市场高度不确定时期都会出现
2019-09-11 11:34:25
换一换
- 如何分清usb-c和type-c的区别
- 中国芯片现状怎样?芯片发展分析
- vga接口接线图及vga接口定义
- 芯片的工作原理是什么?
- 华为harmonyos是什么意思,看懂鸿蒙OS系统!
- 什么是蓝牙?它的主要作用是什么?
- ssd是什么意思
- 汽车电子包含哪些领域?
- TWS蓝牙耳机是什么意思?你真的了解吗
- 什么是单片机?有什么用?
- 升压电路图汇总解析
- plc的工作原理是什么?
- 再次免费公开一肖一吗
- 充电桩一般是如何收费的?有哪些收费标准?
- ADC是什么?高精度ADC是什么意思?
- dtmb信号覆盖城市查询
- EDA是什么?有什么作用?
- 中科院研发成功2nm光刻机
- 苹果手机哪几个支持无线充电的?
- type-c四根线接法图解
- 华为芯片为什么受制于美国?
- 怎样挑选路由器?
- 元宇宙概念股龙头一览
- 锂电池和铅酸电池哪个好?
- 如何进行编码器的正确接线?接线方法介绍
- 什么是场效应管?它的作用是什么?
- 虚短与虚断的概念介绍及区别
- 晶振的作用是什么?
- 大疆无人机的价格贵吗?大约在什么价位?
- amoled屏幕和oled区别
- 苹果nfc功能怎么复制门禁卡
- 单片机和嵌入式的区别是什么
- 复位电路的原理及作用
- BLDC电机技术分析
- dsp是什么意思?有什么作用?
- 苹果无线充电器怎么使用?
- iphone13promax电池容量是多少毫安
- 芯片的组成材料有什么
- 特斯拉充电桩充电是如何收费的?收费标准是什么?
- 直流电机驱动电路及原理图
- 传感器常见类型有哪些?
- 自举电路图
- 苹果笔记本macbookpro18款与19款区别
- 通讯隔离作用
- 新斯的指纹芯片供哪些客户
- 伺服电机是如何进行工作的?它的原理是什么?
- 无人机价钱多少?为什么说无人机烧钱?
- 以太网VPN技术概述
- 手机nfc功能打开好还是关闭好
- 十大公认音质好的无线蓝牙耳机