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

求助:无固定头尾指针的双向循环链表删除方法异常排查

双向循环链表remove方法失效的问题分析与修复

首先,你的问题根源其实不止在remove方法,add方法里的链表节点链接逻辑已经出错了,这导致链表的初始结构就不正确,后续remove自然无法正常工作。我们一步步来排查:

一、Add方法的核心错误

看你的add方法里的这段代码:

listEntry.next = temp.next;
listEntry.previous = temp.next; // 这里错了!应该是temp,不是temp.next
temp.next = listEntry;
temp.next.previous = listEntry.next; // 这里也错了,应该是listEntry

正确的双向链表插入逻辑应该是:

  1. 新节点的next指向temp的下一个节点
  2. 新节点的previous指向当前的temp节点
  3. temp的下一个节点的previous指向新节点
  4. temp的next指向新节点

修正后的add方法代码:

public int add(int position, int value) {
    if (position < 0 || position > size) {
        return -1;
    }
    DEntry listEntry = new DEntry(value, null, null);
    DEntry temp = header;
    // 找到要插入位置的前驱节点
    for (int i = 0; i < position; i++) {
        temp = temp.next;
    }
    // 正确的插入逻辑
    listEntry.next = temp.next;
    listEntry.previous = temp;
    temp.next.previous = listEntry;
    temp.next = listEntry;
    size++;
    return 0;
}

原来的代码把新节点的previous指向了temp.next,还错误地修改了temp.next的previous为listEntry.next,这直接导致链表的双向链接完全混乱,后续节点的引用都是错的。

二、Remove方法的错误

你的remove方法有几个明显的问题:

  1. 边界判断错误:if(position < 0 || position > size) 应该改成 if(position < 0 || position >= size),因为有效位置是0到size-1(size是当前元素个数),position等于size是无效的。
  2. 多余的分支处理:因为header是哨兵节点,不管删除的是第一个还是最后一个元素,都不需要特殊分支,通用的toBeDeleted.previous.next = toBeDeleted.next; toBeDeleted.next.previous = toBeDeleted.previous;就足够处理所有情况。
  3. 错误的position == size分支:这个分支完全不存在,因为最大有效位置是size-1,当size是3的时候,有效位置是0、1、2,position=3是无效的,会被前面的边界判断拦截。

修正后的remove方法代码:

public int remove(int position) {
    if(position < 0 || position >= size) {
        return -1;
    }
    DEntry toBeDeleted = header.next;
    // 找到要删除的节点
    for (int i = 0; i < position; i++) {
        toBeDeleted = toBeDeleted.next;
    }
    int dataOfDeletedNode = toBeDeleted.data;
    // 通用的删除逻辑,无需特殊分支
    toBeDeleted.previous.next = toBeDeleted.next;
    toBeDeleted.next.previous = toBeDeleted.previous;
    size--;
    System.out.println(dataOfDeletedNode);
    return dataOfDeletedNode;
}

另外,你用到的getEntry方法如果内部逻辑有问题,也会影响结果,这里直接把查找逻辑写在remove里更直观,避免依赖未展示的方法。

三、测试场景验证

当执行list.add(0, 10); list.add(1, 20); list.add(0, 30); remove(1);时:

  1. add(0,10):链表结构是header <-> 10 <-> header
  2. add(1,20):链表结构是header <->10 <->20 <->header
  3. add(0,30):链表结构是header <->30 <->10 <->20 <->header
  4. remove(1):删除位置1的节点(即10),最终链表结构是header <->30 <->20 <->header,符合预期。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 04:48:44