我似乎无法弄清楚为什么在双链表末尾插入节点会陷入循环。卡在循环中或为空指针。我也想知道在处理链表或任何数据结构时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;
}
答案 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
将设置为newNode
,next
字段为空。您只想将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。
问题的第二部分,取决于调用函数的要求。