
本文详解单链表按位置删除节点时常见的 nullpointerexception 原因,通过重构初始化逻辑、增加空指针校验、重置遍历指针等关键步骤,提供健壮、可复用的删除实现。
本文详解单链表按位置删除节点时常见的 nullpointerexception 原因,通过重构初始化逻辑、增加空指针校验、重置遍历指针等关键步骤,提供健壮、可复用的删除实现。
在单链表中按索引(位置)删除节点是基础但易错的操作。原始代码试图删除第 2 个节点(期望输出 531),却抛出 NullPointerException: Cannot read field "next" because "temp" is null — 根本原因在于:遍历打印后 temp 已变为 null,后续仍直接访问 temp.next,且未对边界条件(如空链表、越界位置、头节点删除)做防护。
以下是修复后的专业级实现,兼顾正确性、鲁棒性与可读性:
✅ 正确做法:职责分离 + 边界校验 + 指针重置
import java.util.*;
class ListNode {
int data;
ListNode next;
ListNode(int data) {
this.data = data;
this.next = null;
}
// 构建测试链表:5 → 4 → 3 → 1(共4个节点)
public static ListNode buildList() {
ListNode head = new ListNode(5);
head.next = new ListNode(4);
head.next.next = new ListNode(3);
head.next.next.next = new ListNode(1);
return head;
}
// 删除第 n 个节点(n 从 1 开始计数),返回新头节点
public static ListNode deleteAtPosition(ListNode head, int n) {
// 边界检查:空链表或非法位置
if (head == null || n <h3>⚠️ 关键修复点说明</h3>
-
职责分离:链表构建(
buildList)与删除逻辑(deleteAtPosition)彻底解耦,避免在删除方法中混入构造代码,提升可测试性与复用性。 -
空指针防护:
- 循环中添加
temp != null条件,防止越界访问; - 删除前校验
temp.next != null,确保目标节点存在; - 单独处理
n == 1(头节点删除),避免对null.next的无效操作。
- 循环中添加
-
指针重置:每次打印均从
head或新curr开始,杜绝因复用已失效指针导致的 NPE。 -
返回新头节点:支持头节点被删场景(如
n=1),调用方需接收返回值更新引用。
? 使用注意事项
- 位置
n从 1 开始计数(非 0),符合常规语义; - 若
n超出链表长度,方法静默返回原链表(亦可抛出自定义异常); - 原地修改链表结构,时间复杂度 O(n),空间复杂度 O(1);
- 生产环境建议封装为泛型类(如
LinkedList<t></t>),并补充单元测试覆盖边界用例。
遵循以上设计,即可稳定、清晰地完成链表任意位置节点删除,彻底规避 NullPointerException 风险。










