两端的LL插入双倍卡在循环中

时间:2019-01-07 03:47:36

标签: java data-structures

我似乎无法弄清楚为什么在双链表末尾插入节点会陷入循环。卡在循环中或为空指针。我也想知道在处理链表或任何数据结构时public Node是更好还是public void。

public Node insertEnd(int data) {
    Node newNode = new Node(data);
    newNode.next = null;
    if (head == null) {
        head = newNode;
        return newNode;
    }

    Node last = head;
    while(last!=null) {
        last = last.next;
        last.next = newNode;
    }
    newNode.previous = last;
    return newNode;
}

4 个答案:

答案 0 :(得分:2)

好吧,这是因为这部分逻辑

    Node last = head;
    while(last!=null) {
        last = last.next;
        last.next = newNode; //// This shouldn't happen.
    }

一旦链接列表已经创建,您将尝试转到最后一个元素。但是,在遍历期间,您还更改了节点指向的下一个指针。

尝试将您的逻辑更改为:

public Node insertEnd(int data) {
    Node newNode = new Node(data);
    newNode.next = null;
    if (head == null) {
        head = newNode;
        return newNode;
    }

    Node last = head;
    while(last.next != null) {
        last = last.next;
    }
    last.next = newNode;
    newNode.previous = last;
    return newNode;
}

答案 1 :(得分:1)

在您的while循环中:

while(last!=null) {
    last = last.next;
    last.next = newNode;
}

第二行将last.next设置为newNode,因此在下一次迭代中,last将设置为newNodenext字段为空。您只想将last.next设置为newNode一次last.next == null(到达列表末尾时):

while(last.next != null) {
   last = last.next;
}
last.next = newNode;

答案 2 :(得分:1)

对于问题的第二部分,这取决于此API的客户端/调用者期望输出的方式。

您是否正在编写要在正在编写的另一个程序中使用的API?在这种情况下,请考虑将新创建的Node用作此API的返回值是否对您有用,或者将其保留为空是否可以接受。

作为参考,API的Java实现以void作为返回类型。 (https://docs.oracle.com/javase/7/docs/api/java/util/LinkedList.html#addLast(E)

答案 3 :(得分:1)

要回答第一部分,您需要对代码进行以下更改-

 Node last = head;
    while(last.next!=null) { // be careful- it should be last.next!=null instead of last!=null , as it will give null pointer exception.
        last = last.next;    
    }
    last.next = newNode;
    newNode.previous = last;
    return newNode;

作为语句“ last.next = newNode;”在while循环中,第一次迭代本身将最后一个设置为newNode。

问题的第二部分,取决于调用函数的要求。