尝试以递归方式将自定义节点添加到LinkedList的末尾

时间:2015-12-10 22:27:48

标签: java recursion linked-list

您好,我似乎无法在自定义列表的后面添加自定义节点。自定义节点名为ListNode,链接列表名为AddressList

我的程序不会崩溃或抛出任何异常,但它不会在ListNode的末尾添加AddressList。我的addToFront方法有效,但不适用于addToBack方法。我只需要有人查看我的addToBack方法,看看我哪里出错了。

我还必须递归地执行此操作。每个ListNode都有一些值(nametelephoneNumemailaddressdob)以及Next值是ListNode,应该指向ListNode中的下一个AddressList

这是我的代码:

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的后面。任何反馈将不胜感激。

2 个答案:

答案 0 :(得分:2)

这是令人讨厌的代码......

  /*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);
   }

如果你到达null case,你需要将下一个节点设置为一个新节点......我建议这样的事情

   if(currentNode.getNext() == null)
   {
      currentNode.setNext(new ListNode(name, telephoneNum, email, address, dob));
   }

答案 1 :(得分:0)

单独责任

我认为你首先要更好地分离一些职责:而不是每次使用参数来进一步推进该用户的信息,提前构造一个节点,并将其传递给递归方法。这将提高性能并使调用堆栈更小。如下所示:

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。这可能非常有问题:它会将 延续状态附加到您的AddressList 。现在想象一下,稍后你想让你的类多线程,那么这些线程将同时读取和操作这个字段。简而言之:它是糟糕的设计,使用方法变量和/或参数。

所以我们要做的第一件事是获取AddressList的头部并使用:

public void addToBack(ListNode newNode) {
    this.addToBack(this.head,newNode);
}

这还不够:空链表有无头headnull引用。在这种情况下,我们只需将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() currentnull.setNext的基本情况,而不是current的基本情况:对于基本情况,我们只需将newNode的{​​{1}}设置为我们的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); } } 方法两次,可以使最后一个方法更快一些:

CPU acceleration status: HAXM must be updated (version 1.1.4 < 6.0.1).

但这只是一个影响非常有限的细节。