C++ 怎么实现链表 C++单链表节点定义与增删改查【源码】
技术百科
裘德小鎮的故事
发布时间:2026-01-26
浏览: 次 标准C++单链表节点定义为struct ListNode含int val和ListNode* next,构造函数须初始化next为nullptr;头插O(1),尾插O(n),按索引插入需校验index∈[0,size];删除须防内存泄漏;查改操作应复用指针定位逻辑。
怎么定义一个标准的 C++ 单链表节点
单链表节点的核心是「数据 + 指向下一个节点的指针」,C++ 中必须用 struct 或 class 封装,不能只写裸指针。常见错误是忘记初始化 next,导致野指针访问崩溃。
-
next成员必须显式初始化为nullptr(C++11 起),避免悬空指针 - 建议用
struct(默认 public)更简洁;若需封装逻辑,再改用class - 不要在节点里存「前驱指针」——那是双向链表的事,加了反而混淆单链表语义
struct ListNode {
int val;
ListNode* next;
ListNode() : val(0), next(nullptr) {}
ListNode(int x) : val(x), next(nullptr) {}
ListNode(int x, ListNode* next) : val(x), next(next) {}
};头插、尾插、按索引插入怎么写才安全
插入操作最容易出错的是空链表处理和边界越界。头插最简单(时间 O(1)),尾插需遍历(O(n)),按索引插入必须校验 index 是否在 [0, size] 范围内(注意:允许在末尾插入,即 index == size 是合法的)。
- 头插:新建节点 →
newNode->next = head→head = newNode - 尾插:先判空,再用
while (cur->next)找到最后节点,cur->next = newNode - 按索引插入:用
for (int i = 0; i 移动,插入前务必检查cur是否为nullptr
典型错误:insert(5, 10) 在只有 3 个节点的链表中执行,不校验直接访问第 4 个节点 → segmentation fault。
删除节点时为什么总崩?关键检查点在哪
删除失败几乎都源于三类问题:删空链表、删不存在的索引、删头节点后没更新 head。尤其注意:删头节点不能只写 head = head->next,必须先保存原 head 再 delet,否则内存泄漏。
- 删头节点:先
ListNode* tmp = head,再head = head->next,最后delete tmp - 删中间/尾节点:找到待删节点的前驱
prev,执行prev->next = prev->next->next,再delete原节点 - 所有删除前必须检查
head == nullptr,且索引index >= 0
漏掉 delete 是 C++ 链表最隐蔽的 bug —— 程序跑得通但内存持续增长。
查找和修改为什么不能直接返回值而要返回指针
查(get(index))和改(update(index, val))本质都是定位节点。返回 int 值只能读,无法支持后续修改;返回 ListNode* 才能复用查找逻辑,也符合链表「通过指针操作」的本质。
-
get()应返回int,但内部必须先用指针遍历定位,失败时返回约定值(如 -1)并设标志位或抛异常 -
update()必须先调用类似findNode(index)辅助函数获取指针,再改ptr->val = val - 别写
if (get(i) == x) update(i, y)—— 这是两次遍历,O(2n),应合并为一次遍历
实际工程中,findNode() 这类辅助函数不暴露给用户,只在类内复用,否则接口太碎、语义不清。
# 的是
# 都是
# 这是
# 必须先
# 那是
# 两次
# 复用
# public
# c++
# if
# int
# class
# 指针
# 构造函数
# 接口
# 为什么
# node
# delete
# bug
# 封装
# while
# Struct
# 空指针
# 遍历
# for
# 链表
# 只写
相关栏目:
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
AI推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
SEO优化<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
技术百科<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
谷歌推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
百度推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
网络营销<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
案例网站<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
精选文章<?muma echo $count; ?>
】
相关推荐
- Go 中实现 Python urllib.quot
- Windows电脑键盘突然失灵怎么办?(驱动与硬件
- c++中如何求一个数的平方根_c++ sqrt函数
- 如何诊断并终止卡死的 multiprocessin
- Python字符串处理进阶_切片方法解析【指导】
- Win11任务栏怎么放到顶部_Win11修改任务栏
- Python爬虫项目实战教程_Scrapy抓取与存
- Win11如何更改用户账户文件夹名称 Win11修
- Mac如何调整Dock栏大小和位置_Mac程序坞个
- C++中引用和指针有什么区别?(代码说明)
- WindowsUSB驱动安装异常怎么办_USB驱动
- 短链接怎么用php还原_从基础原理到代码实现教学【
- Win11怎么连接蓝牙耳机_Win11蓝牙设备配对
- Windows资源管理器总是卡顿或重启怎么办?(修
- Windows10系统怎么查看CPU核心数_Win
- Win11任务栏天气怎么关闭 Win11隐藏天气小
- php下载安装后memory_limit怎么设置_
- 获取 PHP 文件最后修改时间的正确方法
- php嵌入式多设备通信怎么实现_php同时管理多个
- 如何在Golang中写入JSON文件_保存结构体数
- Win11怎么关闭自动更新 Win11永久关闭系统
- php怎么下载安装后设置错误日志_phpini l
- Golang如何实现基本的用户注册_Golang用
- php打包exe后无法读取环境变量_变量配置方法【
- 如何使用Golang安装API文档生成工具_快速生
- 如何处理“XML格式不正确”错误 常见XML we
- 如何在同包不同文件中正确引用 Go 结构体
- 如何在 Windows 11 中使用 AlomWa
- Win10怎样清理C盘Steam游戏缓存_Win1
- Python数据挖掘核心算法实践_聚类分类与特征工
- 如何在Golang中处理通道发送接收错误_防止阻塞
- Win11怎么更改文件夹图标_自定义Win11文件
- Win11怎么开启HDR模式_Windows 11
- Python技术债务管理_长期维护解析【教程】
- C++如何使用Qt创建第一个GUI窗口?(入门教程
- Win10如何备份注册表_Win10注册表备份步骤
- Win11怎么开启窗口对齐助手_Windows11
- Mac如何查看电池健康百分比_Mac系统信息电源检
- Python深度学习实战教程_神经网络模型构建与训
- Win11怎么关闭边缘滑动手势_Windows11
- Win11怎么开启远程桌面_Win11系统远程桌面
- 如何解决Windows时间不准的问题?(自动同步设
- 如何在Golang中实现微服务负载均衡_Golan
- Windows10如何删除恢复分区_Win10 D
- 电脑的“网络和共享中心”去哪了_Windows 1
- Win10怎样卸载自带Edge_Win10卸载Ed
- Win11怎么设置桌面图标间距_Windows11
- C#怎么创建控制台应用 C# Console Ap
- c++ namespace命名空间用法_c++避免
- Ajax提交表单PHP怎么接收_处理Ajax发送的

QQ客服