数据结构学习——跳表

结构:

多层链表结构,每层是有序的

工作原理 :

  • 最底层包含所有元素,按分数排序
  • 上层为"快速通道",包含部分元素
  • 查找时从顶层开始,逐步降级,类似二分查找

优势 :

  • 插入/删除/查找:O(log N)
  • 实现简单,比平衡树更容易维护
  • 并发性能好,无需复杂的锁机制

代码实现:

python 复制代码
class SkipListNode:
    """跳表节点"""
    def __init__(self, key: float, value: Any, level: int):
        self.key = key  # 排序键
        self.value = value  # 存储的值
        self.forward = [None] * (level + 1)  # 每层的前向指针


class SkipList:
    """跳表实现"""
    
    def __init__(self, max_level: int = 16, p: float = 0.5):
        """
        初始化跳表
        
        Args:
            max_level: 最大层数
            p: 晋升概率
        """
        self.max_level = max_level
        self.p = p
        self.level = 0  # 当前最大层数
        self.header = SkipListNode(float('-inf'), None, max_level)  # 头节点
    
    def random_level(self) -> int:
        """
        随机生成节点层数
        遵循几何分布,概率为 p^level
        """
        level = 0
        while random.random() < self.p and level < self.max_level:
            level += 1
        return level
    
    def search(self, key: float) -> Optional[Any]:
        """
        查找指定键的值
        
        Args:
            key: 要查找的键
            
        Returns:
            找到的值,未找到返回None
        """
        current = self.header
        
        # 从最高层开始查找
        for i in range(self.level, -1, -1):
            while current.forward[i] and current.forward[i].key < key:
                current = current.forward[i]
        
        # 到达第0层,检查是否找到
        current = current.forward[0]
        if current and current.key == key:
            return current.value
        return None
    
    def insert(self, key: float, value: Any) -> None:
        """
        插入键值对
        
        Args:
            key: 键
            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].key < key:
                current = current.forward[i]
            update[i] = current
        
        # 生成随机层数
        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 = SkipListNode(key, 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, key: float) -> bool:
        """
        删除指定键
        
        Args:
            key: 要删除的键
            
        Returns:
            是否删除成功
        """
        # 记录每层的删除位置
        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].key < key:
                current = current.forward[i]
            update[i] = current
        
        # 到达第0层,检查是否找到
        current = current.forward[0]
        if not current or current.key != key:
            return False
        
        # 更新各层的指针
        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 not self.header.forward[self.level]:
            self.level -= 1
        
        return True
    
    def range_query(self, start: float, end: float) -> List[Tuple[float, Any]]:
        """
        范围查询
        
        Args:
            start: 起始键
            end: 结束键
            
        Returns:
            键值对列表
        """
        result = []
        current = self.header
        
        # 从最高层开始查找起始位置
        for i in range(self.level, -1, -1):
            while current.forward[i] and current.forward[i].key < start:
                current = current.forward[i]
        
        # 从起始位置开始收集结果
        current = current.forward[0]
        while current and current.key <= end:
            result.append((current.key, current.value))
            current = current.forward[0]
        
        return result
    
    def get_all(self) -> List[Tuple[float, Any]]:
        """
        获取所有键值对
        
        Returns:
            键值对列表
        """
        result = []
        current = self.header.forward[0]
        while current:
            result.append((current.key, current.value))
            current = current.forward[0]
        return result
    
    def __str__(self) -> str:
        """
        字符串表示
        """
        result = []
        for i in range(self.level, -1, -1):
            level_str = f"Level {i}: "
            current = self.header.forward[i]
            nodes = []
            while current:
                nodes.append(f"({current.key}, {current.value})")
                current = current.forward[i]
            level_str += " -> ".join(nodes)
            result.append(level_str)
        return "\n".join(result)
相关推荐
Betelgeuse7634 分钟前
Django 中间件 4 大钩子 & CBV vs FBV 对比实战
python·中间件·django
92year7 小时前
用Google ADK从零搭一个能调工具的AI Agent:Python实操全过程
python·ai·mcp
爱看大明王朝15667 小时前
磁件学习-磁性元器件的极限计算
笔记·学习
woxihuan1234567 小时前
SQL删除数据时存在依赖关系_设置外键级联删除ON DELETE
jvm·数据库·python
爱滑雪的码农7 小时前
Java基础十七:数据结构
数据结构
东风破1377 小时前
DM8达梦共享存储集群DSC搭建步骤
数据库·学习·dm达梦数据库
多加点辣也没关系7 小时前
数据结构与算法|第二十三章:高级数据结构
数据结构·算法
Jetev8 小时前
如何确定SQL字段是否为空_使用IS NULL与IS NOT NULL
jvm·数据库·python
蛐蛐蛐8 小时前
昇腾910B4上安装新版本CANN的正确流程
人工智能·python·昇腾
星幻元宇VR8 小时前
VR科普大空间:沉浸式公共教育新模式
科技·学习·安全·vr·虚拟现实