
在有序链表去重算法中,`t1.next = null` 是确保结果链表尾部正确截断的必要操作;若省略,会导致尾部残留冗余节点或形成非法结构,引发运行时错误或逻辑错误。
该算法采用双指针(t1 为已去重部分的尾节点,t2 为待检查节点)遍历链表,跳过连续重复值,仅保留每个值的首次出现。其核心逻辑是:当 t1.data == t2.data 时,t2 向前推进以跳过重复;否则,将 t1.next 指向 t2,并更新 t1 = t2,扩展已处理区。
但关键在于——循环终止条件是 t2 == null,而非 t2 到达末尾有效节点。这意味着当 t2 越界为 null 时,t1 仍指向最后一个被保留的有效节点,而该节点的 next 字段可能仍指向已被跳过的重复节点(即“悬垂指针”),未被显式断开。
例如,对链表 1 → 2 → 3 → 3 → null:
- 循环结束时,t1 指向第二个 3(即原链表倒数第二个节点),而 t1.next 仍为 null —— 此时看似无问题;
- 但若输入为 1 → 2 → 3 → 3 → 3 → null,循环结束时 t1 停留在第一个 3,而 t1.next 仍指向第二个 3(未被切断),导致返回链表为 1 → 2 → 3 → 3 → 3 → null,去重失败;
- 更隐蔽的是:若原链表末尾存在多个重复值(如 ... → 5 → 5 → 5 → null),t2 将一路推进至 null,而 t1 停在第一个 5,其 next 仍连着后续重复节点。此时不执行 t1.next = null,结果链表将包含全部重复项,严重违反函数语义。
因此,循环结束后必须强制置空:
t1.next = null;
这一步是链表截断的最终保障,确保 t1 成为新链表真正的尾节点,彻底切断与后续废弃节点的连接。
⚠️ 注意事项:
- 该操作不可省略,即使测试用例看似通过,也可能是巧合(如末尾无重复或重复数为偶数等边界情况);
- 它不依赖于 t1 是否等于 head 或其他条件,是统一的收尾步骤;
- 若链表全为重复值(如 3 → 3 → 3 → null),t1 最终指向首节点,t1.next = null 将正确返回单节点链表 3 → null。
综上,t1.next = null 并非冗余代码,而是算法正确性的最后一道防线——它将逻辑上的“已处理尾部”物理落实为结构上干净、合法的链表终点。










