尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
C++模板双向链表实战:手写STL list
我去年整理代码时翻到一个老项目——手写的 C 模板双向链表。当时我在做一个需要频繁在中间位置插入删除任务的小模块本来可以直接用std::list但我想弄清楚 list 内部到底怎么管理节点、迭代器是怎么工作的干脆按标准库的接口自己实现了一个。这一写反而把模板、指针、内存管理、迭代器这几块 C 里最难啃的骨头全串起来了。这份代码对老手来说属于基本功但对刚学完语法、正准备往数据结构实战走的同学价值比干看 STL 源码大得多。它支持任意数据类型Listint、Liststd::string、List自定义结构体都能存插入删除是 O(1) 复杂度还带了一个能和范围内 for 无缝配合的迭代器。读完这篇文章你可以直接拿到一份可编译的源码更重要的是搞清楚每一步为什么要这么写。1. 双向链表模板的设计思路为什么值得自己写一遍1.1 项目背景从“会用 list”到“能写出 list”当时项目的需求大概是这样的有一批任务对象需要按优先级在任意位置插入删除某个中间任务时也不能拉着后面的数据一起动。std::list本身可以胜任但我还有一个额外的诉求——希望给每个节点加上一个“状态标记”同时随时统计链表中处于特殊状态的节点数量。如果把任务对象包一层再塞进std::list每次插入都要复制如果用裸指针数组插入删除又很别扭。于是“自定义链表”这个方案就成了最顺手的选择。顺着这个需求你会发现自己写链表不是为了造轮子而是为了能在节点结构上做文章。比如侵入式链表节点内部直接内置 prev 和 next 指针、带自定义内存池的链表都必须先理解双向链表的基本实现逻辑才改得动。另外很多公司的面试手撕代码环节都爱考链表把自己完整实现过一遍遇到变体题心里就有底至少不会被“反转链表”“判断环”这类题目问住。1.2 为什么用模板而不是 void*C 语言时代要写一个“通用链表”无非用void*存数据或者用宏展开。void*的最大问题是类型不安全往链表里塞一个int取出来的时候当成double用编译器根本不会拦你运行时直接乱套。宏展开相当于给每种类型复制一份代码可维护性极差改一个逻辑要同步改多处。模板解决的是“代码生成”问题Listint和Liststd::string用同一份模板编译器会在编译期分别生成类型安全的代码。类型检查发生在编译期存错类型就直接编译报错而不是等程序跑起来才爆炸。这一点和 Java 泛型的“类型擦除”不一样C 模板是真正在编译期为每个实例化类型生成对应代码理论上运行效率也更高。这里插一句模板不是没有代价。编译期实例化会让编译时间变长、代码膨胀而且模板的声明和定义不能像普通函数那样分藏在.cpp文件里。这个坑我会在第 4 章单独讲因为它太经典了。1.3 双向链表 vs 单链表一个 prev 指针换来什么单向链表结构简单每个节点只有一个 next 指针遍历只能向前。删除某个节点时你必须先找到它的前驱节点因为要改前驱的 next 指向。这就意味着“删除已知节点”的时间复杂度最坏是 O(n)——哪怕你已经定位到要删的节点了却拿不到它的前驱只能从头部重新走一遍。双向链表给每个节点多存一个 prev 指针删除当前节点时直接通过 prev 找到前驱改两条指针就够了时间复杂度从 O(n) 降到了 O(1)。代价是每个节点多出 8 字节64 位系统下一个指针内存以及插入删除时多维护一次指针操作。在节点本身存了大量数据时这点内存开销可以忽略但如果节点很小、数量很大就要认真算算这笔账了。我项目里选了双向是因为任务对象本身不小8 字节的开销无所谓而删除操作是高频动作必须做到 O(1)。这就是双向和单链表取舍的核心用空间换时间。2. 核心结构拆解节点、迭代器与哨兵节点2.1 节点 Node 的设计细节链表的基础就是节点。节点里至少要有三样东西数据本身、指向前一个节点的指针、指向后一个节点的指针。我的定义是这样的templatetypename T struct Node { T data; Node* prev; Node* next; Node() : data{}, prev(nullptr), next(nullptr) {} explicit Node(const T value) : data(value), prev(nullptr), next(nullptr) {} };用 struct 而不是 class是因为节点内部的数据成员需要被链表直接访问而 struct 的默认访问级别是 public省去手动写一堆public:的啰嗦。这不是风格问题而是实际编码效率问题。data{}是 C
RELATED

相关推荐

ShareX 免费截屏指南:一次按键出图,打码、长截图、自动上传都省时间

ShareX 免费截屏指南:一次按键出图,打码、长截图、自动上传都省时间

ShareX 免费截屏指南:一次按键出图,打码、长截图、自动上传都省时间 【免费下载链接】ShareX ShareX is a free and open-source application that enables users to capture or record any area of their screen with a single keystroke. It also supp…

📅 2026/10/7 6:50:15
STM32Cube_FW_F1 V1.8.0固件包详解:下载安装与工程配置指南

STM32Cube_FW_F1 V1.8.0固件包详解:下载安装与工程配置指南

简介:STM32Cube_FW_F1_V1.8.0.zip是意法半导体官方发布的STM32F1系列HAL库固件包,面向嵌入式开发者,提供硬件抽象层API,可显著提升应用开发效率并简化底层驱动编写。压缩包共10641个文件,包含丰富的C/H源码、工程文件&…

📅 2026/9/26 6:09:16
OpenCore Legacy Patcher 手把手:3 步在老 Mac 上装最新 macOS

OpenCore Legacy Patcher 手把手:3 步在老 Mac 上装最新 macOS

OpenCore Legacy Patcher 手把手:3 步在老 Mac 上装最新 macOS 【免费下载链接】OpenCore-Legacy-Patcher Experience macOS just like before 项目地址: https://gitcode.com/GitHub_Trending/op/OpenCore-Legacy-Patcher 你有一台 2015 年的 MacBook,硬件还够用,却只能…

📅 2026/10/6 19:39:56
MORE NEWS

更多资讯

📰

YOLOv8在木材缺陷检测中的应用与优化

1. 项目概述:当YOLOv8遇上木材质检 在木材加工行业,传统的人工质检方式正面临三大痛点:效率低下(每小时仅能检测200-300块板材)、标准不统一(不同质检员对缺陷的判定存在主观差异)以及人力成本攀…

📰

Ollama双模式部署:本地与云端大模型灵活切换指南

1. 项目概述:当小龙虾遇上Ollama的奇妙组合去年夏天我在调试本地大模型时,厨房里煮着的小龙虾突然给了我灵感——为什么不能像烹饪一样,把本地模型和云端服务像食材般自由搭配?这个看似无厘头的想法,最终催生了这套双模…

📰

HiClaw AI工具本地部署与性能优化指南

1. HiClaw本地部署全流程解析HiClaw作为一款新兴的AI工具,其本地部署能力让不少开发者跃跃欲试。不同于云端服务,本地部署能提供更好的数据隐私保护和定制化开发空间。我最近在团队内部完成了HiClaw的本地部署,过程中踩过不少坑,也…

📰

AI服务退款流程全解析:嘎嘎降AI实操指南

1. 项目概述 "不达标可退款"这个承诺在各类AI服务领域越来越常见,但实际执行情况如何?作为连续使用过7款不同AI工具的深度用户,我最近完整体验了嘎嘎降AI的退款流程,发现其中有不少值得分享的细节。这篇文章将用4000字详…

📰

t3code 桌面客户端:统一管理 Claude Code、Codex 与 Cursor 的 Electron 实践

1. 从 t3code 这个标题说起:它到底想解决什么问题第一次看到 “t3code” 这个标题,我脑子里蹦出来的不是某个具体产品,而是一类很典型的需求:把散落在终端里的 AI 编码助手,塞进一个像样的桌面壳子里。热词里反复出现 …

📰

格式即协议:重构LLM智能体交互的结构化范式

1. 这篇MIT论文到底在说什么?不是“提示工程又赢了”,而是交互逻辑被重新定义 最近刷到一条技术圈热帖:“MIT新论文炸出AI智能体底层逻辑”——标题里那个“简化交互格式比推理提示更能改善LLM智能体决策”,乍看像又一篇讲怎么写更…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬