You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在自定义单向链表中搜索并移除指定节点(Java实现)

链表节点删除问题的修复方案

你的核心问题是没有跟踪待删除节点的前驱节点,当前代码在找到目标节点时,错误地修改了目标节点自身的next指针,这相当于跳过了目标节点的下一个节点,而非删除目标节点本身。要解决这个问题,我们需要同时跟踪当前节点和它的前驱节点,或者通过调整遍历逻辑来定位前驱。

问题代码的核心错误

原代码中,当temp.equals(song)为真时,执行temp.next = song.next——这其实是让目标节点自己跳过它的下一个节点,而不是让前驱节点跳过目标节点。而且遍历条件!temp.equals(temp.next)也存在逻辑漏洞:当链表只有一个节点时,temp.next是END,temp不等于temp.next,会进入循环,但此时如果这个节点是目标节点,修改temp.next后,链表的头节点并没有更新,导致头节点依然指向已删除的节点。

修复后的代码实现

我们需要分情况处理头节点删除、中间节点删除,同时跟踪前驱节点:

public int remove(Song song) {
    // 空链表直接返回-1
    if (first.equals(Song.END)) {
        return -1;
    }

    // 处理头节点就是目标节点的情况
    if (first.equals(song)) {
        first = first.next;
        return 0;
    }

    // 跟踪前驱节点和当前节点
    Song prev = first;
    Song current = prev.next;
    int index = 1;

    // 遍历到链表末尾(END节点)为止
    while (!current.equals(Song.END)) {
        if (current.equals(song)) {
            // 让前驱节点的next指向当前节点的后继,完成删除
            prev.next = current.next;
            return index;
        }
        prev = current;
        current = current.next;
        index++;
    }

    // 遍历完没找到目标节点
    return -1;
}

代码逻辑解释

  1. 空链表判断:如果first是END,说明链表没有有效节点,直接返回-1。
  2. 头节点特殊处理:如果目标节点是头节点,直接将first更新为头节点的下一个节点,不需要找前驱。
  3. 前驱+当前节点遍历:用prev记录当前节点的上一个节点,current遍历每个节点。当找到目标节点时,修改prev.next为current.next,这样就跳过了current(即待删除节点)。
  4. 遍历终止条件:当current等于END时,说明已经遍历完所有有效节点,终止循环。

额外注意点

  • 你的Song类的equals方法只比较title和artist,这符合业务逻辑,但要确保传入的song参数的title和artist不为空(当前构造方法已经保证了这一点,所以没问题)。
  • 原代码中的while (!temp.equals(temp.next))会在temp是END时停止,但遍历有效节点时,应该以current是否为END作为终止条件,这样能覆盖所有有效节点。

内容的提问来源于stack exchange,提问作者KodaNotABear

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 17:09:57