0

0

c++怎么实现跳表SkipList数据结构_c++ 概率层级设计与快速查找【案例】

冰火之心

冰火之心

发布时间:2026-01-03 18:41:14

|

761人浏览过

|

来源于php中文网

原创

跳表层级用随机概率而非固定高度,因随机晋升(如p=0.5)可保证平均O(n)空间与O(log n)查找,避免固定层数导致的重平衡、内存浪费和扩展性差。

c++怎么实现跳表skiplist数据结构_c++ 概率层级设计与快速查找【案例】

跳表的层级设计为什么用随机概率而非固定高度

跳表不是靠预设层数来加速查找,而是让每个新节点以 p = 0.5(或 1/41/e)的概率向上“晋升”一层。这样能保证平均空间复杂度为 O(n),同时查找期望时间仍是 O(log n)。硬编码固定层数(比如统一 5 层)会导致:插入时频繁重平衡、内存浪费严重、无法动态适应数据规模。

实践中推荐用 rand() % 2 == 0 模拟 p = 0.5,或更严谨地用 static std::random_device rd; static std::mt19937 gen(rd()); std::bernoulli_distribution d(0.5);。避免用 rand() % k 做多级判断——容易因低比特劣质导致层级分布偏差。

核心结构体怎么组织才便于插入和删除

每个节点必须持有指向**同一层右侧节点**和**下一层同位置节点**的指针,不能只存“下一个”或“下面一个”。典型结构是:std::vector forward;,其中 forward[i] 指向第 i 层的后继节点。头节点(header)需初始化为最大可能层数(如 MAX_LEVEL = 32),但实际使用中每层只在有节点跨越时才有效。

  • 插入前必须从顶层开始逐层搜索,记录每层最后访问的节点(即 update[i]),这是删除和插入修正指针的关键
  • 删除时只需沿 update 数组向下修复指针,无需重新搜索
  • 节点构造时用 new Node(level) 分配 forward 数组,避免 vector 动态扩容干扰缓存局部性

如何正确实现 search / insert / delete 的指针更新逻辑

三者共用同一套“搜索路径捕获”逻辑:从 header 出发,对每一层 i 从左到右移动,直到 next->key >= target,记录该层最后停留的节点为 update[i]区别仅在于后续操作:

立即学习C++免费学习笔记(深入)”;

Veo
Veo

Google 最新发布的 AI 视频生成模型

下载
Node* SkipList::search(int key) {
    Node* x = header;
    for (int i = level; i >= 0; i--) {
        while (x->forward[i] && x->forward[i]->key < key)
            x = x->forward[i];
    }
    x = x->forward[0];
    return x && x->key == key ? x : nullptr;
}

void SkipList::insert(int key, int value) { std::vector> update(MAX_LEVEL + 1, header); Node x = header; for (int i = level; i >= 0; i--) { while (x->forward[i] && x->forward[i]->key < key) x = x->forward[i]; update[i] = x; } x = new Node(key, value, randomLevel()); if (x->level > level) { for (int i = level + 1; i <= x->level; i++) update[i] = header; level = x->level; } for (int i = 0; i <= x->level; i++) { x->forward[i] = update[i]->forward[i]; update[i]->forward[i] = x; } }

注意:level 是当前跳表最高非空层(从 0 开始计),不是节点数;randomLevel() 返回的是新节点层数(至少为 0),不是全局最大层数。

为什么多线程环境下不能直接加锁整个 insert

对整个跳表加互斥锁(如 std::mutex)会彻底串行化所有操作,失去跳表本应具备的并发优势。实际工程中更常用的是:对**每层链表单独加锁**,或采用无锁(lock-free)设计(如基于 CAS 的原子指针更新)。但无锁实现极难保证正确性——尤其在节点删除后被其他线程误读 forward[i] 指针时,极易出现 ABA 问题或悬垂指针。

简单起见,若必须支持并发,建议:

  • 读操作(search)完全无锁(前提是节点删除后内存不立即释放,可用 RCU 或 epoch-based reclamation)
  • 写操作按层粒度加锁:插入时只锁涉及的层数(0..x->level),而非全部 MAX_LEVEL
  • 避免在持有锁期间调用用户自定义函数(如比较器),以防死锁

跳表真正难的不是写对单线程版本,而是删掉某节点后,如何让所有层级的 forward 指针同步失效——这点哪怕在教科书实现里也常被简化忽略。

相关专题

更多
golang结构体相关大全
golang结构体相关大全

本专题整合了golang结构体相关大全,想了解更多内容,请阅读专题下面的文章。

194

2025.06.09

golang结构体方法
golang结构体方法

本专题整合了golang结构体相关内容,请阅读专题下面的文章了解更多。

186

2025.07.04

treenode的用法
treenode的用法

​在计算机编程领域,TreeNode是一种常见的数据结构,通常用于构建树形结构。在不同的编程语言中,TreeNode可能有不同的实现方式和用法,通常用于表示树的节点信息。更多关于treenode相关问题详情请看本专题下面的文章。php中文网欢迎大家前来学习。

531

2023.12.01

C++ 高效算法与数据结构
C++ 高效算法与数据结构

本专题讲解 C++ 中常用算法与数据结构的实现与优化,涵盖排序算法(快速排序、归并排序)、查找算法、图算法、动态规划、贪心算法等,并结合实际案例分析如何选择最优算法来提高程序效率。通过深入理解数据结构(链表、树、堆、哈希表等),帮助开发者提升 在复杂应用中的算法设计与性能优化能力。

17

2025.12.22

线程和进程的区别
线程和进程的区别

线程和进程的区别:线程是进程的一部分,用于实现并发和并行操作,而线程共享进程的资源,通信更方便快捷,切换开销较小。本专题为大家提供线程和进程区别相关的各种文章、以及下载和课程。

475

2023.08.10

Python 多线程与异步编程实战
Python 多线程与异步编程实战

本专题系统讲解 Python 多线程与异步编程的核心概念与实战技巧,包括 threading 模块基础、线程同步机制、GIL 原理、asyncio 异步任务管理、协程与事件循环、任务调度与异常处理。通过实战示例,帮助学习者掌握 如何构建高性能、多任务并发的 Python 应用。

136

2025.12.24

数据库Delete用法
数据库Delete用法

数据库Delete用法:1、删除单条记录;2、删除多条记录;3、删除所有记录;4、删除特定条件的记录。更多关于数据库Delete的内容,大家可以访问下面的文章。

268

2023.11.13

drop和delete的区别
drop和delete的区别

drop和delete的区别:1、功能与用途;2、操作对象;3、可逆性;4、空间释放;5、执行速度与效率;6、与其他命令的交互;7、影响的持久性;8、语法和执行;9、触发器与约束;10、事务处理。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

208

2023.12.29

从零到实战:Python 编程系统入门专题
从零到实战:Python 编程系统入门专题

本专题面向零编程基础及初学者,系统讲解 Python 编程语言的核心知识与实战技巧。内容涵盖 Python 基础语法、数据结构、函数与模块、常用标准库、简单算法思维,以及真实应用场景下的小项目实战。通过循序渐进的学习路径,帮助读者快速建立编程思维,掌握 Python 在数据处理、自动化脚本及日常开发中的实际应用能力,为后续深入学习 Web 开发、数据分析或人工智能打下坚实基础。

8

2026.01.05

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
HTML5/CSS3/JavaScript/ES6入门课程
HTML5/CSS3/JavaScript/ES6入门课程

共102课时 | 6.6万人学习

前端基础到实战(HTML5+CSS3+ES6+NPM)
前端基础到实战(HTML5+CSS3+ES6+NPM)

共162课时 | 18.5万人学习

第二十二期_前端开发
第二十二期_前端开发

共119课时 | 12.2万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号