【问题标题】:java-linked list sublist methodjava链表子列表方法
【发布时间】:2014-10-15 22:47:47
【问题描述】:

我正在尝试编写一个 subList 方法,该方法返回一个包含当前对象列表的列表,包括索引 fromIndextoIndex 之间。

例如,如果我的列表包含

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;
}

【问题讨论】:

  • 您似乎缺少类声明,某些方法不在类中。
  • 您没有显示您在哪里创建代码并将值分配给您的列表。您确定没有将节点添加到列表中,而该列表中的 next 字段已设置为列表中的其他内容吗?

标签: java linked-list nodes sublist


【解决方案1】:

我认为您应该创建一个新节点,而不是将原始列表的节点添加到新列表(即子列表):

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...

【讨论】:

    【解决方案2】:

    如果我们只查看您的 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 时算法会短路,无需处理一堆永远不可能成为结果集一部分的额外节点,而且在列表中有循环的情况下,就不会陷入无限循环。

    【讨论】:

    • 顺便说一句,为了完整起见,如果 toIndex 抛出异常也是个好主意
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-07-03
    • 2013-08-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-16
    • 1970-01-01
    相关资源
    最近更新 更多