数据结构学习——跳表

结构:

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

工作原理 :

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

优势 :

  • 插入/删除/查找: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)
相关推荐
飞翔中文网7 分钟前
Java学习笔记之抽象类
java·笔记·学习
Metaphor69217 分钟前
使用 Python 在 Excel 中查找并高亮显示
python·信息可视化·excel
ID_1800790547319 分钟前
淘宝商品详情数据接口深度解析:架构、鉴权、数据结构与实战
数据结构·架构
Esaka_Forever39 分钟前
few‑shot learning(少样本学习)
人工智能·学习
旦莫42 分钟前
AI测试Agent的两种架构路径:谁做主控?
人工智能·python·架构·自动化·ai测试
散峰而望1 小时前
【算法练习】算法练习精选:陶陶摘苹果(基础+升级)、Music Notes、字串变换,你能AC几道?
数据结构·c++·算法·leetcode·贪心算法·github·动态规划
搬石头的马农1 小时前
从零配置Claude自动修Bug:6步打造全自动开发流程
java·人工智能·python·bug·ai编程
暗夜猎手-大魔王1 小时前
转载--Hermes Agent 04 | Agent 主循环:一次对话背后发生了什么
人工智能·python·算法
Wonderful U1 小时前
基于Python+Django的在线题库与智能阅卷系统:从痛点分析到完整实现
开发语言·python·django
码语智行1 小时前
拦截器、接口限流、过滤器、防重发/幂等性功能说明
开发语言·网络·python