我正在尝试编写一个subList方法,该方法返回一个由当前对象列表组成的列表,包含在索引fromIndex
和toIndex
之间。
例如,如果我有由
组成的列表9 11 20 23 28 30
我打电话给subList(1,4)
,我应该得到一个新的
11 20 23 28
返回。
对于我的subList()方法,我尝试运行它但最终进入无限循环。当下一个节点为空时,它应该退出循环,但这不会发生,所以我需要帮助弄清楚为什么这个无限循环正在发生以及我能做些什么。任何帮助表示赞赏!
private class Node<N extends Comparable<N>> {
private N data;
private Node<N> next;
}
private Node<L> head;
public List() {
head = null;
}
private void add(Node<L> node) {
if(head == null) {
head=node;
} else {
getFinal().next = node;
}
}
public Node<L> getFinal(){
Node<L> node = head;
while (node.next != null) {
node = node.next;
}
return node;
}
public int size() {
if (head == null) return 0;
int counter = 0;
for (Node<L> curr = head; curr != null; curr = curr.next)
counter++;
return counter;
}
public List<L> subList(int fromIndex, int toIndex) throws IndexOutOfBoundsException {
if(fromIndex < 0 || fromIndex > size()-1 || toIndex < 0 || toIndex > size()-1) {
throw new IndexOutOfBoundsException();
}
List<L> n = new List<L>();
Node<L> startNode = head;
int counter = 0;
while(startNode != null) {
if(counter >= fromIndex && counter <= toIndex) { //infinite loop happens here
n.add(startNode);
}
startNode=startNode.next;
counter++;
}
return n;
}
答案 0 :(得分:0)
我认为您应该创建一个新节点,而不是将原始列表的节点添加到新列表(即子列表)中:
while(startNode!=null){
if(counter>=fromIndex && counter<=toIndex){ //infinite loop happens here
Node<L> nl = new Node<L>();
nl.data = startNode.data;
n.add(nl);
}
startNode=startNode.next;
counter++;
}
否则,这将发生。假设您有以下列表:
1 -> 2 -> 3 -> null
现在,请致电subList(1, 2)
。这将致电n.add(2)
。这将调用getFinal()
,但getFinal()
仍然会返回3(而不是2),因为2.next仍然指向3。
因此,在3 之后添加并获得无限循环,因为2.next = 3:
1 -> 2 -> 3 -> 2
^ ^ <-- Cycle in your list...
答案 1 :(得分:0)
如果我们只是查看你的subList方法的while循环,你的退出条件没有意义。你有:
while(startNode != null) {
if(counter >= fromIndex && counter <= toIndex) { //infinite loop happens here
n.add(startNode);
}
startNode=startNode.next;
counter++;
}
你应该:
while(startNode != null && counter <= toIndex) {
if(counter >= fromIndex) {
n.add(startNode);
}
startNode=startNode.next;
counter++;
}
简而言之,你要说:循环,直到没有更多的非空节点或者直到我们传递toIndex为止。这个解决方案不仅效率更高,因为算法会在达到toIndex时短路,不会处理一堆永远不会成为结果集的一部分的额外节点,而且在列表中有循环的情况下也是如此。 ,你不会遇到无限循环。