dummy节点的不同声明方法和使用场景
一、什么是“哑节点”?
在链表问题中,哑节点(dummy node)是一种常用的技术,它的作用是:
- 使得在删除头结点或处理链表边界时,能够避免很多特殊情况的判断。
- 通常把它定义为一个结构体变量,并让它的
next指向原始链表的头结点。
二、哑节点的定义
错误做法:声明为指针
ListNode* dummy;
dummy->next = head; // 错误:此时 dummy 并没有被初始化
这里 dummy 是一个 指针,但没有初始化它指向有效的内存。所以当你尝试访问 dummy->next 时,会导致 未定义行为(因为 dummy 并没有指向有效的内存位置)。
正确做法:声明为结构体变量
ListNode dummy; // 正确:dummy 是一个结构体变量
dummy.next = head;
这样 dummy 就是一个 结构体变量,它的 next 字段可以正确地指向链表的头节点,它占用内存并初始化,可以安全访问。
三、结构体变量 vs 结构体指针
1) 结构体变量
-
结构体变量会在 栈上分配内存,当它声明时,它的内存空间已经在栈中开辟好,因此可以直接访问其成员。
示例:
ListNode dummy; dummy.next = head; // 直接通过 dummy 访问 next
2) 结构体指针
-
结构体指针没有指向任何有效的内存,必须先为它分配内存,通常用
malloc或calloc来分配空间。示例:
ListNode* dummy = (ListNode*)malloc(sizeof(ListNode)); // 动态分配内存 dummy->next = head; // 正常工作
但注意:如果你没有初始化指针,指向的是一个随机地址,它会导致错误。
四、为什么使用结构体变量而不是指针变量?
1) 避免未初始化指针的问题
如果你使用指针(ListNode* dummy),而没有初始化它,就会出现未定义行为:
ListNode* dummy;
dummy->next = head; // 错误:dummy 没有指向有效内存
这种情况下程序会崩溃或行为不可预测。
2) 结构体变量更简单
用结构体变量更简单,直接声明 ListNode dummy;,这样就能在栈上分配内存,并且它会自动初始化。你无需担心内存的分配和释放问题(如果不需要动态分配)。
3) 不需要使用 malloc 和 free
当你使用结构体指针时,通常需要 malloc 动态分配内存,并且使用完后需要 free 释放内存。如果不小心忘记释放内存,可能会导致内存泄漏。而结构体变量会在函数结束时自动销毁,不会有内存泄漏问题。
五、总结
- 结构体变量:是栈上的自动变量,分配内存和初始化都比较直接,不容易出错。
- 结构体指针:需要动态分配内存,如果不初始化或者管理不当,会出现内存错误。
因此,在实现 dummy 节点时,直接声明为结构体变量是最安全、最常见的做法。
dummy节点的使用场景
一句话总结
凡是可能操作到头结点,或者需要统一处理“前驱节点”的链表问题,都应该使用 dummy 节点。
一、什么时候必须用 dummy?
1️⃣ 删除类问题(最典型)
当删除的节点可能是头结点时,必须用 dummy。
例如:
- 删除倒数第 n 个节点(LC19)
- 删除指定值节点
- 删除重复节点(LC82 / LC83)
因为删除需要:
prev->next = prev->next->next;
如果要删的是 head,就没有 prev → dummy 充当 head 的前驱。
2️⃣ 在头部插入节点
例如:
- 头插法构建链表
- 反转链表时头部不断变化
dummy 可以始终固定在最前面,避免 head 频繁变化带来的麻烦。
3️⃣ 需要返回新头节点的操作
例如:
- 合并两个有序链表(LC21)
- 分割链表(LC86)
- 重排链表(LC143)
dummy 帮助统一构造新链表,然后直接 return dummy.next。
4️⃣ 双指针找前驱节点的场景
例如:
- 快慢指针删除节点
- 找中点后修改结构
dummy 统一 slow 的起点,避免 slow 为 NULL。
二、典型必须用 dummy 的题型
| 题型 | 为什么需要 dummy |
|---|---|
| 删除节点 | 防止删除 head 时无前驱 |
| 构造新链表 | 方便挂接 next |
| 多指针操作 | 保证 slow 永远有前驱 |
| 分段重组链表 | 统一链表起点 |
三、不用 dummy 容易出什么问题?
- 删除头节点要写特判
- head 被改丢
- prev 为空崩溃
- 逻辑分叉变复杂
四、一句记忆口诀(强烈建议记)
“删头、插头、换头、统一前驱 —— 一律加 dummy”
这是链表里最重要的工程化技巧之一,408 和 LeetCode 高频必用。

浙公网安备 33010602011771号