Java 尝试递归地将自定义节点添加到LinkedList的末尾
嗨,我似乎很难将自定义节点添加到我的链接列表的后面。自定义节点称为Java 尝试递归地将自定义节点添加到LinkedList的末尾,java,recursion,linked-list,Java,Recursion,Linked List,嗨,我似乎很难将自定义节点添加到我的链接列表的后面。自定义节点称为ListNode,链接列表称为AddressList public void addToBack(String name, String telephoneNum, String email, String address, String dob) { /*Base case.*/ /*If the next node in the AddressList is null add the ListNode to t
ListNode
,链接列表称为AddressList
public void addToBack(String name, String telephoneNum, String email, String address, String dob) {
/*Base case.*/
/*If the next node in the AddressList is null add the ListNode to that node.*/
if(currentNode.getNext() == null) {
currentNode = currentNode.getNext();
currentNode = new ListNode(name, telephoneNum, email, address, dob);
}
/*Recursive case.*/
/*If the AddressList still has nodes after the currentNode, keep going.*/
else {
currentNode = currentNode.getNext();
addToBack(name, telephoneNum, email, address, dob);
}
currentNode = head;
}
我的程序不会崩溃或抛出任何异常,但它不会在我的地址列表
末尾添加列表节点
。我的addToFront
方法有效,但我的addToBack
方法无效。我只需要有人看看我的addToBack
方法,看看哪里出了问题
我也必须递归地这样做。每个列表节点
都有一些值(名称
,电话号码
,电子邮件
,地址
,dob
),还有一个下一个
值,它是一个列表节点
,应该指向地址列表
中的下一个列表节点
public void addToBack(String name, String telephoneNum, String email, String address, String dob) {
/*Base case.*/
/*If the next node in the AddressList is null add the ListNode to that node.*/
if(currentNode.getNext() == null) {
currentNode = currentNode.getNext();
currentNode = new ListNode(name, telephoneNum, email, address, dob);
}
/*Recursive case.*/
/*If the AddressList still has nodes after the currentNode, keep going.*/
else {
currentNode = currentNode.getNext();
addToBack(name, telephoneNum, email, address, dob);
}
currentNode = head;
}
这是我的代码:
public ListNode(String name, String telephoneNum, String email, String address, String dob) {
this.name = name;
this.telephoneNum = telephoneNum;
this.email = email;
this.address = address;
this.dob = dob;
}
public ListNode getNext() {
return next;
}
public void setNext(ListNode link) {
next = link;
}
上面的代码部分是ListNode
的构造函数,以及在AddressList
中获取和设置下一个链接的方法
public void addToBack(String name, String telephoneNum, String email, String address, String dob) {
/*Base case.*/
/*If the next node in the AddressList is null add the ListNode to that node.*/
if(currentNode.getNext() == null) {
currentNode = currentNode.getNext();
currentNode = new ListNode(name, telephoneNum, email, address, dob);
}
/*Recursive case.*/
/*If the AddressList still has nodes after the currentNode, keep going.*/
else {
currentNode = currentNode.getNext();
addToBack(name, telephoneNum, email, address, dob);
}
currentNode = head;
}
以上是我的addToBack
方法。我只是不明白为什么我的程序没有抛出异常或将ListNode
添加到AddressList
的后面。任何反馈都将不胜感激。以下是令人不快的代码
/*Base case.*/
/*If the next node in the AddressList is null add the ListNode to that node.*/
if(currentNode.getNext() == null)
{
currentNode = currentNode.getNext();
currentNode = new ListNode(name, telephoneNum, email, address, dob);
}
如果达到空值,则需要将下一个节点设置为新节点。。。我建议这样做
if(currentNode.getNext() == null)
{
currentNode.setNext(new ListNode(name, telephoneNum, email, address, dob));
}
分开的责任
我认为您首先最好将一些职责分开:不要每次都使用参数进一步推进该用户的信息,而是提前构造一个节点,并将其传递给递归方法。这将稍微提高性能,并使调用堆栈更小。比如:
public void addToBack(String name, String telephoneNum, String email, String address, String dob) {
addToBack(new ListNode(name,telephoneNum,email,address,dob));
}
然后你需要想出一个方法,比如:
public void addToBack(ListNode newNode) {
//TODO: implement
//...
}
避免对象中的方法状态(或连续状态)
第二个问题是,您的AddressList
似乎有一个字段currentNode
,该字段在递归过程中被修改。这可能会有很大的问题:它会将一个延续状态附加到地址列表
。现在想象一下,稍后您希望使类成为多线程的,那么这些线程将同时读取和操作该字段。简而言之:这是糟糕的设计,使用方法变量和/或参数
因此,我们要做的第一件事是获取地址列表的头部,并使用它:
public void addToBack(ListNode newNode) {
this.addToBack(this.head,newNode);
}
这是不够的:空链表没有标题:head
是null
引用。在这种情况下,我们只需将head
设置为newNode
,就完成了。因此,我们将其改写为:
public void addToBack(ListNode newNode) {
if(this.head == null) {
this.head = newNode;
} else {
this.addToBack(this.head,newNode);
}
}
现在显然我们仍然需要实现核心方法:
public void addToBack(ListNode current, ListNode newNode) {
//TODO: implement
//...
}
实现核心方法
正如您自己所指出的,基本上有两种情况:基本情况下,当前
的.getNext()
为空
,而非空的情况:对于基本情况,我们只需将当前
的.setNext
设置为我们的新节点
:
if(current.getNext() == null) {
current.setNext(newNode);
}
在后一种情况下,我们前进:获取.getNext
节点,并递归调用该方法:
else {
addToBack(current.getNext(),newNode);
}
或全部:
public void addToBack(String name, String telephoneNum, String email, String address, String dob) {
//separate responsibilities, by constructing the node first
addToBack(new ListNode(name,telephoneNum,email,address,dob));
}
public void addToBack(ListNode newNode) {
//do not use a continuation state in a class, fetch the head, inspect the head and if not null pass to the recursion method
if(this.head == null) {
this.head = newNode;
} else {
this.addToBack(this.head,newNode);
}
}
public void addToBack(ListNode current, ListNode newNode) {
//generic method that adds the node at the end
if(current.getNext() == null) {//base case: current is the last node
current.setNext(newNode);
} else {//recursive case, current is not the next node
addToBack(current.getNext(),newNode);
}
}
通过防止调用.getNext
方法两次,可以使最后一个方法更快一些:
public void addToBack(ListNode current, ListNode newNode) {
//generic method that adds the node at the end
ListNode nx = current.getNext();
if(nx == null) {//base case: current is the last node
current.setNext(newNode);
} else {//recursive case, current is not the next node
addToBack(nx,newNode);
}
}
但这只是一个影响非常有限的细节。您不会将新节点设置为任何地方的下一个节点。因此,节点之间没有链接。更多注意空检查块什么是currentNode
。在您的问题中,您不会谈论这段信息:通常,链表只引用第一个节点(头部)。看起来好像在类的状态中使用了延续状态。这可能会成为有问题的设计。这很有效,谢谢!!递归使我头晕目眩。