求助:无固定头尾指针的双向循环链表删除方法异常排查
双向循环链表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
正确的双向链表插入逻辑应该是:
- 新节点的
next指向temp的下一个节点 - 新节点的
previous指向当前的temp节点 - temp的下一个节点的
previous指向新节点 - 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方法有几个明显的问题:
- 边界判断错误:
if(position < 0 || position > size)应该改成if(position < 0 || position >= size),因为有效位置是0到size-1(size是当前元素个数),position等于size是无效的。 - 多余的分支处理:因为header是哨兵节点,不管删除的是第一个还是最后一个元素,都不需要特殊分支,通用的
toBeDeleted.previous.next = toBeDeleted.next; toBeDeleted.next.previous = toBeDeleted.previous;就足够处理所有情况。 - 错误的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);时:
- add(0,10):链表结构是header <-> 10 <-> header
- add(1,20):链表结构是header <->10 <->20 <->header
- add(0,30):链表结构是header <->30 <->10 <->20 <->header
- remove(1):删除位置1的节点(即10),最终链表结构是header <->30 <->20 <->header,符合预期。
内容的提问来源于stack exchange,提问作者user8918738
相关产品推荐
相关产品推荐

