Java循环链表无限循环问题:List类修改方案咨询
解决循环链表打印/删除时的无限循环问题
嘿,我来帮你搞定这个循环链表的无限循环坑!先给你看修正后的Link和CircularList实现,再给你拆解问题根源和修改点:
1. Link 类代码
public class Link { public int data; public Link next; public Link(int data) { this.data = data; this.next = null; } public void displayLink() { System.out.print("[" + data + "] "); } }
2. CircularList 类代码
public class CircularList { private Link last; // 用尾节点维护循环链表,首尾操作更高效,也更容易避免指针混乱 public CircularList() { last = null; } public boolean isEmpty() { return last == null; } // 尾部插入(保留你已实现的正确逻辑) public void insertLast(int data) { Link newLink = new Link(data); if (isEmpty()) { last = newLink; newLink.next = last; // 单个节点时自循环 } else { newLink.next = last.next; // 新节点指向头节点 last.next = newLink; // 原尾节点指向新节点 last = newLink; // 更新尾节点 } } // 打印链表:解决无限循环的核心! public void displayList() { if (isEmpty()) { System.out.println("链表为空"); return; } Link current = last.next; // 从头节点开始遍历 // 用do-while保证至少执行一次(哪怕只有一个节点),遍历到回到头节点就停止 do { current.displayLink(); current = current.next; } while (current != last.next); System.out.println(); } // 删除头节点 public Link deleteFirst() { if (isEmpty()) { return null; } Link first = last.next; if (first == last) { // 链表只有一个节点的情况 last = null; // 清空链表,避免残留自循环节点 } else { last.next = first.next; // 尾节点指向新的头节点,维持循环 } return first; } // 删除指定数据的节点(处理所有边界情况) public Link delete(int key) { if (isEmpty()) { return null; } Link current = last.next; Link previous = last; // 遍历查找目标节点,直到回到头节点停止 do { if (current.data == key) { // 分四种情况处理,保证循环不中断 if (current == last && current == last.next) { // 唯一节点 last = null; } else if (current == last.next) { // 删除头节点 last.next = current.next; } else if (current == last) { // 删除尾节点 last = previous; last.next = current.next; } else { // 删除中间节点 previous.next = current.next; } return current; } previous = current; current = current.next; } while (current != last.next); return null; // 没找到对应节点 } }
为啥你之前会无限循环?
你遇到的问题几乎是循环链表新手必踩的坑,主要是这两个原因:
- 打印时没有正确的终止条件:循环链表没有
null结尾,如果用普通的while(current != null)遍历,永远不会停下来——因为节点的next永远指向另一个节点,不会出现null。所以必须从首节点开始,遍历到回到首节点就停止,用do-while刚好适配这种场景(哪怕只有一个节点也能正确打印)。 - 删除节点后没维护好循环指针:
- 如果删除的是链表唯一的节点,没把
last置为null,会残留一个自循环的节点,遍历的时候就会无限绕圈。 - 删除头/尾节点时,没更新
last或者last.next的指向,会导致循环断裂或者形成错误的循环链,遍历的时候就会停不下来。
- 如果删除的是链表唯一的节点,没把
- 额外建议:用尾节点维护循环链表比头节点更合理,首尾插入/删除都能做到O(1)时间复杂度,也更容易避免指针混乱。
你可以把自己的代码和上面的对比,看看是不是在这些点上出了问题~
内容的提问来源于stack exchange,提问作者Devin
相关产品推荐
相关产品推荐

