Java开发

跳表(Skip List) 介绍

2024-09-07  本文已影响0人  _浅墨_

跳表详解

跳表(Skip List) 是一种动态数据结构,最早由 William Pugh 于 1990 年提出。它通过在有序链表的基础上引入多级索引结构,使得在有序链表中可以快速进行查找、插入和删除操作。跳表的平均时间复杂度为 O(log n),在最坏情况下为 O(n)

1. 跳表结构

跳表的核心思想是通过建立多级“跳跃”索引来减少遍历节点的数量。我们可以把跳表想象成一个多层的链表结构:

这种多级索引结构使得查找、插入和删除操作都能够通过从上往下跳跃,逐步缩小查找范围。

2. 跳表的时间复杂度

3. 使用场景

跳表适用于以下场景:

4. 示例代码

下面是用 Python 实现的跳表结构,示例中包括跳表的插入、查找、删除功能:

import random

class Node:
    def __init__(self, value=None, level=0):
        self.value = value
        self.forward = [None] * (level + 1)  # 创建一个 forward 列表,表示该节点的“前进”指针

class SkipList:
    MAX_LEVEL = 16  # 最大索引层数
    P = 0.5  # 随机生成层数的概率

    def __init__(self):
        self.level = 0  # 当前的索引层数
        self.header = Node(None, self.MAX_LEVEL)  # 跳表的头节点

    def random_level(self):
        level = 0
        while random.random() < self.P 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  # 记录该层的最后一个小于待插入值的节点

        # 插入新的节点
        level = self.random_level()  # 随机生成新节点的层数
        if level > self.level:
            for i in range(self.level + 1, level + 1):
                update[i] = self.header  # 新增层索引,指向头节点
            self.level = level

        new_node = Node(value, level)
        for i in range(level + 1):
            new_node.forward[i] = update[i].forward[i]
            update[i].forward[i] = new_node

    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]
        if current and current.value == value:
            return True
        return False

    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

# 测试跳表
if __name__ == "__main__":
    skiplist = SkipList()
    
    # 插入一些数据
    for num in [3, 6, 7, 9, 12, 19, 17]:
        skiplist.insert(num)
    
    # 查找数据
    print(skiplist.search(7))  # 输出 True
    print(skiplist.search(15))  # 输出 False
    
    # 删除数据
    skiplist.delete(6)
    print(skiplist.search(6))  # 输出 False

5. 总结

上一篇 下一篇

猜你喜欢

热点阅读