c++如何实现一个跳表(Skip List)_c++替代平衡树的高效数据结构【源码】


跳表是一种概率性多层链表结构,平均查找复杂度O(log n),通过随机提升和分层索引实现高效操作,比平衡树更易实现。

c++如何实现一个跳表(skip list)_c++替代平衡树的高效数据结构【源码】

<p>跳表(Skip List)是一种概率性数据结构,用多层链表实现快速查找,平均时间复杂度为 O(log n),最坏 O(n),但实践中非常稳定,且比红黑树、*L 等平衡树更易实现和调试。C++ 中无需依赖复杂旋转逻辑,只需维护多级前向指针即可。</p>

<H3>核心设计思路:分层 + 随机提升</H3>
<p>跳表本质是“带索引的有序链表”:底层是完整有序链表(Level 0),上层是稀疏子集(每层节点以约 50% 概率“晋升”到上一层)。查找时从最高层开始向右跳,遇到过大值就下移,最终在底层定位目标。</p>
<p>关键点:</p>
<ul>
  <li>每个节点不是固定层数,而是插入时随机决定层数(如用 rand() % 2 == 0 不断提升,直到失败,最大层数可设上限,如 32)</li>
  <li>所有层共享同一组键值,仅指针结构分层</li>
  <li>头节点(head)需初始化为 max_level 层,每层 next 指针初始为 nullptr</li>
  <li>为简化边界处理,可设哨兵尾节点(或用 nullptr 表示结尾)</li>
</ul>

<H3>节点定义与内存管理</H3>
<p>节点需存储 key、value(支持 map 语义)、以及动态长度的 next 指针数组:</p><p><span>立即学习</span>“<a href="https://pan.quark.cn/s/6e7abc4abb9f" style="text-decoration: underline !important; color: blue; font-weight: bolder;" rel="nofollow" target="_blank">C++免费学习笔记(深入)</a>”;</p>
<pre class="brush:php;toolbar:false;"><font size="2">struct SkipListNode {
    int key;
    std::string value;  // 可泛化为 template <typename V>
    std::vector<SkipListNode*> next;

    SkipListNode(int k, const std::string& v, int level) 
        : key(k), value(v), next(level, nullptr) {}
};</font>

不推荐用 raw new/delete 手动管理 —— 可封装在类内用 std::vector 或 std::unique_ptr 统一释放;若追求极致性能,可用内存池(但初版跳表建议先忽略)。

Waifulabs Waifulabs

一键生成动漫二次元头像和插图

Waifulabs 347 查看详情 Waifulabs

插入与查找的核心逻辑

查找(search)是插入/删除的基础:记录每层最后一个小于 key 的节点(update 数组),用于后续链接修复:

<font size="2">SkipListNode* search(int key) {
    auto x = head;
    for (int i = current_level - 1; i >= 0; i--) {
        while (x->next[i] && x->next[i]->key < key) {
            x = x->next[i];
        }
    }
    x = x->next[0];  // 落到 level 0,检查是否命中
    return (x && x->key == key) ? x : nullptr;
}</font>

插入(insert)流程:

  • 先执行 search 过程,同时记录每层“前驱节点”到 update[i]
  • 生成新节点,层数 random_level()(如:while (rand() & 1 && lvl
  • 更新 current_level(若新层数更高)
  • 逐层设置新节点 next[i] = update[i]->next[i],再令 update[i]->next[i] = 新节点

完整可运行精简版(支持 int→string 映射)

<font size="2">#include <iostream>
#include <vector>
#include <random>
#include <algorithm>

struct SkipListNode {
    int key;
    std::string value;
    std::vector<SkipListNode*> next;

    SkipListNode(int k, const std::string& v, int level) 
        : key(k), value(v), next(level, nullptr) {}
};

class SkipList {
    SkipListNode* head;
    int current_level;
    const int max_level = 16;
    std::mt19937 rng{std::random_device{}()};

    int random_level() {
        int lvl = 1;
        std::bernoulli_distribution d(0.5);
        while (d(rng) && lvl < max_level) ++lvl;
        return lvl;
    }

public:
    SkipList() : current_level(1) {
        head = new SkipListNode(0, "", max_level);
    }

    ~SkipList() {
        auto x = head;
        while (x) {
            auto next = x->next[0];
            delete x;
            x = next;
        }
    }

    void insert(int key, const std::string& value) {
        std::vector<SkipListNode*> update(max_level, head);
        auto x = head;

        for (int i = current_level - 1; i >= 0; i--) {
            while (x->next[i] && x->next[i]->key < key)
                x = x->next[i];
            update[i] = x;
        }

        x = x->next[0];
        if (x && x->key == key) {
            x->value = value;  // 更新已存在 key
            return;
        }

        int lvl = random_level();
        if (lvl > current_level) {
            for (int i = current_level; i < lvl; ++i)
                update[i] = head;
            current_level = lvl;
        }

        x = new SkipListNode(key, value, lvl);
        for (int i = 0; i < lvl; ++i) {
            x->next[i] = update[i]->next[i];
            update[i]->next[i] = x;
        }
    }

    std::string find(int key) {
        auto x = head;
        for (int i = current_level - 1; i >= 0; i--) {
            while (x->next[i] && x->next[i]->key < key)
                x = x->next[i];
        }
        x = x->next[0];
        return (x && x->key == key) ? x->value : "";
    }
};

// 使用示例
int main() {
    SkipList sl;
    sl.insert(3, "three");
    sl.insert(1, "one");
    sl.insert(5, "five");
    std::cout << sl.find(1) << "\n"; // one
    std::cout << sl.find(4) << "\n"; // (empty)
}</font>

该实现支持重复 key 的覆盖写入,无锁(单线程安全),内存自动释放。如需并发,可在关键路径加 std::shared_mutex(读多写少场景下性能仍优于平衡树锁粒度)。

基本上就这些 —— 跳表不复杂但容易忽略层级同步和内存释放细节,掌握 update 数组和 random_level 就抓住了主干。

以上就是c++++如何实现一个跳表(Skip List)_c++替代平衡树的高效数据结构【源码】的详细内容,更多请关注其它相关文章!


# go  # ai  # c++  # ios  # stream  # 无锁  # red  # node  # 汕头市b2b全网营销推广代理  # qq推广营销技巧  # 博乐网站优化推广公司  # 雪场营销推广  # 坂田网站推广哪家好  # 莱西网站建设模板  # 福田全国网站推广怎么做  # 苏州seo网站管理平台  # 黄冈网站关键字优化  # seo看什么书好  # 相关文章  # 只需  # 与其他  # 更易  # 如何使用  # 如何实现  # 是一种  # 链表  # 层数  # 数据结构 


相关栏目: 【 Google疑问12 】 【 Facebook疑问10 】 【 优化推广96088 】 【 技术知识133117 】 【 IDC资讯59369 】 【 网络运营7196 】 【 IT资讯61894 】


相关推荐: sublime怎么快速在浏览器中预览HTML_sublime配置View in Browser教程  WooCommerce 新客户订单自动添加管理员备注教程  HTML Canvas文本样式定制指南:解决外部字体加载与应用难题  管理打开的编辑器:固定、分组和关闭技巧  基于键值条件高效映射 Pandas DataFrame 多列数据  Win10锁屏时间怎么设置 Win10调整自动锁屏时间方法  LINUX怎么查看显卡信息_LINUX查看GPU状态  《画加》约稿流程  Mac如何开启画中画模式_Mac Safari浏览器视频画中画功能  todesk如何添加信任设备_todesk信任设备设置教程  如何在CSS中使用过渡制作按钮边框渐变_border-color transition实现  PHP 4 函数中引用参数的默认值限制与解决方案  Golang如何实现HTTP请求重试机制_Golang HTTP请求错误处理策略  TikTok笔记文字无法编辑如何解决 TikTok笔记文字编辑优化方法  照片整理的黄金法则是怎样的? 理解“收集-筛选-归档-备份”四步流程  Lar*el Eloquent中通过Join查询关联数据表:解决多行子查询问题  word页码灰色不能用如何解决  《幻兽帕鲁》手游帕鲁捕捉技巧分享  Keras中Convolution2D层及其核心辅助层详解  驱动人生:游戏修复指南  纯CSS实现自适应宽度与响应式布局的水平按钮组  mysql镜像配置如何设置用户权限组_mysql镜像配置用户组与权限分级管理方法  更换小红书群背景怎么换?小红书群规则怎么设置?  163邮箱网页版入口 163邮箱在线使用  《360浏览器》设置摄像头权限方法  composer 提示 "requires ext-soap" 缺少 SOAP 扩展怎么办?  ExcelSCAN与LAMBDA如何创建自定义移动平均函数_SCAN实现任意窗口期移动平均计算  PHP安全加载非公开目录图片与动态内容类型处理指南  search中maxlength属性用法解析  《桃源记2》资源采集攻略  惠普电脑BIOS界面看不懂怎么办_HP电脑BIOS功能选项解读与设置  Mac怎么关闭按键声音_Mac键盘打字音效设置  Win10运行窗口在哪里打开 Win10调出运行命令框快捷键【技巧】  PHP中获取HTTP响应状态消息:方法与限制  Golang如何使用crypto/md5生成哈希_Golang MD5哈希生成方法  《大学搜题酱》官网地址登录  谷歌浏览器如何查找和删除恶意软件 谷歌浏览器内置安全清理工具使用教程  win11讲述人怎么关闭 Win11屏幕朗读辅助功能禁用方法【技巧】  CSS过渡与滚动滚动事件结合应用_scroll与transition动画  百度小说看书时如何翻页_百度小说手动翻页与自动翻页设置  虫虫助手如何更新游戏  多闪电脑版下载_多闪PC端模拟器使用  《环球网校》设置报考省市方法  J*aScript事件处理:优化键盘输入与表单提交的实践指南  德邦快递查询入口登录官网 德邦快递单号查询系统入口  b站网页版入口 哔哩哔哩官方网站直接进入  如何用mysql开发用户注册登录功能_mysql用户注册登录数据库设计  拷贝漫画2025网页版入口 拷贝漫画官网免费看全集  实现可重用自定义Python Range类  以下哪一个是适应长期护理制度发展而设立的新职业 

 2025-12-13

了解您产品搜索量及市场趋势,制定营销计划

同行竞争及网站分析保障您的广告效果

点击免费数据支持

提交您的需求,1小时内享受我们的专业解答。

运城市盐湖区信雨科技有限公司


运城市盐湖区信雨科技有限公司

运城市盐湖区信雨科技有限公司是一家深耕海外推广领域十年的专业服务商,作为谷歌推广与Facebook广告全球合作伙伴,聚焦外贸企业出海痛点,以数字化营销为核心,提供一站式海外营销解决方案。公司凭借十年行业沉淀与平台官方资源加持,打破传统外贸获客壁垒,助力企业高效开拓全球市场,成为中小企业出海的可靠合作伙伴。

 8156699

 13765294890

 8156699@qq.com

Notice

We and selected third parties use cookies or similar technologies for technical purposes and, with your consent, for other purposes as specified in the cookie policy.
You can consent to the use of such technologies by closing this notice, by interacting with any link or button outside of this notice or by continuing to browse otherwise.