[英]How do I fix that infinite loop on a custom double linked list?
I have created a custom LinkedList and I am trying to have a method that partitions it based on a value.我创建了一个自定义 LinkedList 并且我正在尝试使用一种基于值对其进行分区的方法。 There is no need to maintain the order so I thought of adding values less than x to the head of the list and values equal or greater to the tail.没有必要保持顺序,所以我想将小于 x 的值添加到列表的头部,并将值等于或大于尾部。
Nonetheless, there is an infinite loop happening as node.next is never null when the check is happening.尽管如此,还是会发生无限循环,因为在检查发生时 node.next 永远不会为空。
Here is the code:这是代码:
public class LinkedList<T extends Comparable<T>> {
private int size = 0;
private Node<T> head = null;
private Node<T> tail = null;
public int size() {
return size;
}
public boolean isEmpty() {
return size == 0;
}
/**
*
* @param t the new element to be added at the end of the list
* NOTE: null items are not allowed
*
* @return true if added
*/
public boolean add(T t) {
if (t == null) {
return false;
}
// if head is null add as head
if (head == null) {
head = new Node<>(t, null, null);
tail = head;
} else {
Node<T> newTail = new Node<>(t, tail, null);
tail.next = newTail;
tail = newTail;
}
size++;
return true;
}
void partition(T value) {
Node<T> node = head;
while (node != null) {
Node<T> prev = node.previous;
Node<T> next = node.next;
if (node.data.compareTo(value) >= 1) {
// should go to tail
if (node != tail) {
prev.next = node.next;
next.previous = node.previous;
tail.next = node;
node.previous = tail;
node.next = null;
tail = node;
}
} else {
// should go to head
if (node != head) {
prev.next = node.next;
if (null != next) {
next.previous = node.previous;
}
head.previous = node;
node.next = head;
head = node;
}
}
node = next;
}
head.previous = null;
tail.next = null;
}
public T getFirst() {
return head.data;
}
public Node<T> getHead() {
return head;
}
public T getLast() {
return tail.data;
}
private static class Node<T extends Comparable<T>> {
T data;
Node<T> previous;
Node<T> next;
Node(T data, Node<T> previous, Node<T> next) {
this.data = data;
this.previous = previous;
this.next = next;
}
}
}
Test case to reproduce:要重现的测试用例:
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import java.util.Arrays;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
public class LinkedListTest {
private LinkedList<Integer> linkedList;
@BeforeMethod
public void setUp() {
linkedList = new LinkedList<>();
}
@Test
public void testPartition() {
linkedList.add(0);
linkedList.add(9);
linkedList.add(2);
linkedList.add(5);
linkedList.add(4);
linkedList.add(7);
linkedList.add(1);
int[] actual = new int[linkedList.size()];
linkedList.partition(5);
for (int i = 0; i < linkedList.size(); ++i) {
actual[i] = linkedList.get(i);
}
System.out.println(Arrays.toString(actual));
}
}
Let's say your list has two items: A->B and both A and B > value (so "should go to tail").假设您的列表有两个项目:A->B 以及 A 和 B > 值(因此“应该到尾”)。 Begin your code.开始你的代码。 Node A > value, so A gets put on the tail.节点 A > 值,因此 A 位于尾部。 So now your list is B->A and B is the 'next' node and A is now the tail.所以现在你的列表是 B->A,B 是“下一个”节点,A 现在是尾部。
The next iteration of the loop looks at Node B. Node B > value, so B is put on the tail.循环的下一次迭代查看节点 B。节点 B > 值,因此 B 放在尾部。 Now your list is A->B and A is the 'next' node and B is now the tail.现在您的列表是 A->B,A 是“下一个”节点,B 现在是尾部。 Obviously this is an infinite loop.显然这是一个无限循环。
To solve this in the spirit of how this code is written, before starting the loop do this:要本着编写此代码的精神解决此问题,请在开始循环之前执行以下操作:
last_node = tail;
Now, just before you have node = next;
现在,就在你有node = next;
之前node = next;
do this:做这个:
if(node == last_node) break;
In the example above, last_node
points to B. The loop processes A then B then quits because B is last_node
.在上面的例子中, last_node
指向 B。循环处理 A 然后 B 然后退出,因为 B 是last_node
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.