讲师中心 微信公众号
AI工具推荐 视频效率加速

C++怎么实现跳表(Skip List)_C++有序结构替代红黑树【查找】

小浩小哥_3899

小浩小哥_3899

发布时间:2026-03-09 14:35:23

|

746人浏览过

|

来源于php中文网

原创

跳表值得手写因其并发友好、内存局部性优、可控性强;需避免层级越界、断链、硬编码层数等错误,next数组须内联固定长度以提升缓存效率。

c++怎么实现跳表(skip list)_c++有序结构替代红黑树【查找】

跳表在 C++ 里为什么值得手写而不是直接用 std::set

跳表不是 STL 标准组件,std::set 底层是红黑树,O(log n) 查找但常数大、内存局部性差;跳表靠多层链表 + 随机提升实现均摊 O(log n),插入/删除更易并发,且自己控制层级和随机策略时,能压测、调参、嵌入自定义比较逻辑——比如你正做日志索引或实时排序缓存,又不想引入 Boost 或第三方库,手写一个轻量跳表反而更可控。

常见错误现象:find() 返回空指针却没检查层级越界;insert() 后忘记更新前驱数组导致断链;随机层数硬编码为 16,实际数据量小却浪费内存。

  • 层级上限别设死,按 log2(n) 动态估算(n 是预期最大节点数),初始可设为 16,但运行时根据实际 size 调整
  • 随机提升概率必须是 0.5(即每次抛硬币),用 rand() & 1 比 rand() % 2 更快且无 bias
  • 所有节点的 next 数组大小必须统一为当前最大层级,哪怕某次插入只到第 2 层——否则遍历时指针访问会越界

skip_list_node 的内存布局怎么避免 cache line 断裂

跳表性能吃内存布局很重:每个节点带一个 next 指针数组,如果数组长度不固定或用 std::vector 动态分配,指针分散在堆上,一次查找要跨多个 cache line。必须把 next 做成固定长度的内联数组。

示例结构体关键点:

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

C++14
C++14

C++14 对 C++11 的修正与增强版本,适合旧系统维护和较老工具链兼容。

下载
struct skip_list_node {
    int key;
    std::string value; // 实际业务字段
    skip_list_node* next[16]; // 必须是 [16],不能是 std::unique_ptr<skip_list_node*>[]
};
  • next[16] 放在结构体末尾,用 malloc(sizeof(skip_list_node) + 16 * sizeof(skip_list_node*)) 分配整块内存
  • 不要用 std::array<skip_list_node*, 16>,它会让编译器在结构体里塞 padding,破坏紧凑性
  • 如果 key 是小整型(如 int),把它放结构体最前面,利于 CPU 预取时提前拿到比较值

插入时怎么维护 update 数组而不漏层

跳表插入本质是“从顶层往下找每层最后一个 ≤ key 的节点”,把这些节点记进 update[] 数组,再逐层把新节点插到它们后面。漏掉某一层,就会导致该层链表断裂,后续 find() 在那层直接跳过新节点。

典型错误:for (int i = current_level - 1; i >= 0; i--) 循环里,没对每一层都执行 update[i] = x,而是只在找到位置时才赋值。

  • 初始化 update 数组全为 head 指针:skip_list_node* update[16]; for (int i = 0; i
  • 搜索时每下降一层,先保存当前节点到 update[i],再沿 next[i] 走:“先存后走”,不是“走到再存”
  • 新节点层级为 lvl,则只对 i = 0 到 lvl-1 层执行插入,更高层不用动

查不到节点时 find() 返回什么最安全

返回 nullptr 看似自然,但容易掩盖边界问题:比如 key 小于所有节点,或跳表为空,find() 走完顶层就停了,根本没进任何 next 指针——这时候返回 nullptr 没问题;但如果用户想“找 floor key”,就需要返回小于等于 key 的最大节点,此时 nullptr 就不够用了。

更稳妥的做法是让 find() 返回一对指针:std::pair<skip_list_node*, bool>,bool 表示是否精确命中。但多数场景下,只要文档写清行为,返回 nullptr 即可。

  • 绝对不要返回野指针或未初始化的局部变量地址
  • 如果支持重复 key,find() 应返回第一个匹配节点,而非任意一个——这由插入时“相等时往右走”的约定保证
  • 调试时可在 find() 开头加 assert:assert(head_ != nullptr);,空跳表应单独处理,不进主逻辑

跳表最难调的永远不是算法逻辑,而是指针赋值顺序和内存释放时机:delete 节点前,必须确保所有层级的前驱节点的 next[i] 都已绕过它,否则删完立刻触发 use-after-free。这个点没有银弹,只能靠 ASan + 反复压测。

热门AI工具

更多
豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

Lovart
Lovart Hot

一款面向视觉设计创作的AI设计平台,可通过智能体和画布工作流辅助制作海报、Logo、网页、PPT及其他视觉内容。

切问学术

切问学术是一款AI论文写作工具,复旦大学NLP团队推出的AI学术智能体。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

Seko
Seko Hot

一款AI视频创作工具,主要用于商汤科技推出的创编一体的AI短视频创作Agent,适合需要提升相关任务效率的用户。

Laper
Laper Hot

Laper是专为编剧、导演和制片人推出的 AI 原生剧本创作工具。

墨刀AI
墨刀AI Hot

一款AI图像与设计工具,主要用于产品经理的专属智能体,适合需要提升相关任务效率的用户。

咔片AIPPT

一款在线AI演示文稿制作工具,可根据主题和内容需求辅助生成PPT结构与页面,提高演示材料制作效率。

相关专题

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

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

4794

2025.06.09

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

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

4931

2025.07.04

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

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

4794

2025.06.09

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

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

4931

2025.07.04

string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

6479

2023.08.02

int占多少字节
int占多少字节

int占4个字节,意味着一个int变量可以存储范围在-2,147,483,648到2,147,483,647之间的整数值,在某些情况下也可能是2个字节或8个字节,int是一种常用的数据类型,用于表示整数,需要根据具体情况选择合适的数据类型,以确保程序的正确性和性能。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

3145

2024.08.29

c++怎么把double转成int
c++怎么把double转成int

本专题整合了 c++ double相关教程,阅读专题下面的文章了解更多详细内容。

4048

2025.08.29

C++中int的含义
C++中int的含义

本专题整合了C++中int相关内容,阅读专题下面的文章了解更多详细内容。

2785

2025.08.29

Gradle插件开发入门教程
Gradle插件开发入门教程

本专题介绍Gradle插件开发的基本流程,涵盖插件类编写、自定义任务注册、扩展参数设计和插件应用方法,帮助你理解插件如何组织构建逻辑,减少多个项目之间的重复配置。

0

2026.10.22

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C++ Core Guidelines
C++ Core Guidelines

共0课时 | 0人学习

C++ Reference
C++ Reference

共0课时 | 0人学习

C++ 官方标准说明
C++ 官方标准说明

共0课时 | 0人学习

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

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn