数据结构学习——跳表

结构:

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

工作原理 :

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

优势 :

  • 插入/删除/查找: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)
相关推荐
21439652 小时前
Less如何构建CSS样式库_通过继承机制优化组件化开发
jvm·数据库·python
qq_413847402 小时前
如何通过 reflect.Value 获取切片的底层值
jvm·数据库·python
zhangchaoxies2 小时前
JavaScript中单线程事件循环EventLoop的卡顿预警
jvm·数据库·python
InfinteJustice2 小时前
Laravel Blade 中高效筛选并限制关联分类数据的实践指南
jvm·数据库·python
2301_815279522 小时前
SQL分组求和结果显示为零的技巧_利用IFNULL或CASE语句
jvm·数据库·python
zhangchaoxies2 小时前
Python Web应用负载均衡方案_结合Nginx权重设置实现高可用
jvm·数据库·python
qq_334563552 小时前
C#怎么操作SQLite加密数据库 C#如何创建和使用加密的SQLite数据库文件保护数据【数据库】
jvm·数据库·python
gCode Teacher 格码致知2 小时前
Python提高:软件测试中Fixture机制-由Deepseek产生
开发语言·python
qq_413847402 小时前
Redis如何利用Lua实现秒杀资格与库存的双重校验
jvm·数据库·python