Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/311.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/spring-mvc/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 尝试递归地将自定义节点添加到LinkedList的末尾_Java_Recursion_Linked List - Fatal编程技术网

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
。在您的问题中,您不会谈论这段信息:通常,链表只引用第一个节点(头部)。看起来好像在类的状态中使用了延续状态。这可能会成为有问题的设计。这很有效,谢谢!!递归使我头晕目眩。