删除单向链表指定值节点需先找前驱,头节点要单独处理并更新head;按索引删需校验边界、用i=index-1找前驱;delete后须置空指针防野指针;仅传节点指针无法删除,因无前驱且参数值传递。

删除单向链表中指定值的节点
必须先遍历找到目标节点的前驱,不能直接用 delete 当前节点指针后就结束——否则会丢失前驱对后续节点的连接。典型错误是删掉头节点后没更新 head 指针,导致整个链表“消失”。
实操要点:
- 单独处理头节点:若
head->val == target,需执行head = head->next; delete old_head; - 非头节点:用
prev和curr双指针遍历,找到后执行prev->next = curr->next; delete curr; - 找不到时要检查
curr == nullptr,避免解引用空指针
按位置索引删除节点(如第n个)
索引从 0 开始更符合 C++ 习惯,但容易错算边界。删第 0 个就是删头节点;删第 size 个则越界——必须提前校验 index = size。
关键细节:
立即学习“C++免费学习笔记(深入)”;
- 遍历时用计数器
i匹配index - 1找前驱(不是index),否则会多走一步 - 如果链表为空(
head == nullptr),任何索引都非法,应直接返回 - 删完记得
size--(如果你维护了长度字段)
释放节点内存时常见的野指针问题
delete ptr 只释放内存,不自动把 ptr 设为 nullptr。之后若再次解引用该指针(比如误判为未删除),就是未定义行为,调试极难定位。
安全做法:
- 每次
delete后立即置空:delete curr; curr = nullptr; - 前驱指针操作前加判空:
if (prev != nullptr) prev->next = curr->next; - 头节点删除后务必重置:
delete head; head = nullptr;
为什么不能只传节点指针进去删除?
因为单向链表没有前驱指针,仅靠 Node* target 无法修改其前一个节点的 next 字段。C++ 中函数参数是值传递,void deleteNode(Node* node) 改不了外部指针本身。
可行方案只有两种:
- 传入二级指针:
void deleteNode(Node** head, int val),这样能修改*head - 或传入链表对象封装(推荐):
class LinkedList { public: void remove(int val); private: Node* head; };
裸指针操作链表时,最易忽略的是所有权归属——谁负责 new,谁就必须负责 delete,且不能重复释放。一旦混用智能指针和原始指针,问题会立刻爆发。










