跳跃列表(Skip List)详解

什么是跳跃列表?

跳跃列表是一种概率性的数据结构,旨在提高链表的搜索、插入和删除效率。它通过在普通链表的基础上增加多个层次,以实现更快的访问速度。跳跃列表的设计灵感来源于跳跃图(Skip Graph)和多层索引的概念,适合需要频繁进行动态数据操作的场景。

跳跃列表的基本结构

跳跃列表由多个层次的链表组成。最底层的链表包含所有的元素,而上层的链表则通过指针跳过一些节点,从而加快搜索速度。每个节点不仅存储自己的值,还持有一个指针数组,指向同层的下一个节点。

结构示例

  • 头节点:通常存储负无穷,方便搜索。
  • 节点:每个节点包含一个值和多个指针,指向相同或更高层的节点。

操作实现

1. 节点类

首先定义节点类,包含节点的值和指针数组。

python 复制代码
class Node:
    def __init__(self, value, level):
        self.value = value
        self.forward = [None] * (level + 1)  # 指针数组

2. 跳跃列表类

实现跳跃列表类,包含插入、删除和搜索的方法。

python 复制代码
import random

class SkipList:
    def __init__(self, max_level):
        self.max_level = max_level
        self.header = Node(float('-inf'), max_level)  # 头节点
        self.level = 0  # 当前层数

    def random_level(self):
        level = 0
        while random.random() < 0.5 and level < self.max_level:
            level += 1
        return level

    def insert(self, value):
        update = [None] * (self.max_level + 1)  # 保存前驱节点
        current = self.header
        
        for i in range(self.level, -1, -1):
            while current.forward[i] and current.forward[i].value < value:
                current = current.forward[i]
            update[i] = current

        current = current.forward[0]  # 最底层的下一个节点
        
        if current is None or current.value != value:
            new_level = self.random_level()  # 随机层数
            if new_level > self.level:
                for i in range(self.level + 1, new_level + 1):
                    update[i] = self.header
                self.level = new_level

            new_node = Node(value, new_level)  # 新节点
            for i in range(new_level + 1):
                new_node.forward[i] = update[i].forward[i]
                update[i].forward[i] = new_node

    def delete(self, value):
        update = [None] * (self.max_level + 1)
        current = self.header
        
        for i in range(self.level, -1, -1):
            while current.forward[i] and current.forward[i].value < value:
                current = current.forward[i]
            update[i] = current

        current = current.forward[0]

        if current and current.value == value:
            for i in range(self.level + 1):
                if update[i].forward[i] != current:
                    break
                update[i].forward[i] = current.forward[i]

            while self.level > 0 and self.header.forward[self.level] is None:
                self.level -= 1

    def search(self, value):
        current = self.header
        for i in range(self.level, -1, -1):
            while current.forward[i] and current.forward[i].value < value:
                current = current.forward[i]
        current = current.forward[0]
        return current is not None and current.value == value

示例使用

python 复制代码
skip_list = SkipList(max_level=4)
skip_list.insert(3)
skip_list.insert(6)
skip_list.insert(7)
skip_list.insert(9)
skip_list.insert(12)
skip_list.insert(19)

print(skip_list.search(7))  # True
print(skip_list.search(15))  # False

skip_list.delete(3)
print(skip_list.search(3))  # False

时间复杂度分析

  1. 搜索 (Search): 平均时间复杂度为 O(log n),因其可以在多层中快速跳跃。
  2. 插入 (Insert): 平均时间复杂度也是 O(log n),通过随机选择层数实现高效插入。
  3. 删除 (Delete): 平均时间复杂度同样为 O(log n)。

最坏情况

在最坏情况下,所有元素都在同一层,此时时间复杂度为 O(n)。不过这种情况的概率较低,跳跃列表在实际应用中通常表现良好。

总结

跳跃列表是一种高效的概率性数据结构,适合动态数据的处理。通过引入随机性,跳跃列表在搜索、插入和删除操作中都能实现平均 O(log n) 的时间复杂度,成为解决许多实际问题的优秀选择。

如果你对跳跃列表有更多的疑问或想要进一步探讨的内容,欢迎在评论区留言!

相关推荐
gugucoding11 小时前
31. 【C语言】堆栈与队列的实现
c语言·开发语言·数据结构·链表
ChaoZiLL12 小时前
我的数据结构3——链表(link list)
数据结构·链表
王老师青少年编程14 小时前
2026年6月GESP真题及题解(C++七级):消消乐
数据结构·c++·算法·真题·gesp·2026年6月
海清河晏11114 小时前
数据结构 | 二叉搜索树
数据结构·c++·visual studio
Yang_jie_0315 小时前
笔记:数据结构(顺序表)
数据结构·windows·笔记
ywl47081208717 小时前
常用的集合类有哪些?比如List如何排序?
list·java基础
绝世番茄19 小时前
鸿蒙原生ArkTS布局方式之List+swipeAction侧滑菜单深度解析
华为·list·harmonyos·鸿蒙
一个初入编程的小白20 小时前
数据结构:栈
数据结构
我命由我1234520 小时前
方差(实例实操、与标准差的区别)
java·数据结构·算法·数据分析·java-ee·intellij-idea·idea
努力努力再努力wz21 小时前
【高性能网络库与HTTP Server系列】:基于主从 Reactor 模型实现高性能 C++ 网络库与 HTTP Server
开发语言·网络·数据结构·数据库·c++·网络协议·http