【问题标题】:Print Singly linked list in reverse using recursion - Java使用递归反向打印单链表 - Java
【发布时间】:2013-05-15 04:42:18
【问题描述】:

您好,我在尝试使用递归以相反顺序打印单链表时遇到了一点麻烦。我看过一些例子,但我的方法不带任何参数。我想按以下格式打印出来:

input: [1, 2, 3, 4, 5] and output:[5, 4, 3, 2, 1]

first 指的是我的单链表中的第一个节点,我使用StringBuilder 来构建我的列表,以便我可以在最后返回它。

这是我目前所拥有的:

public String printReverse() {
    StringBuilder myString = new StringBuilder("[");
    if (head != null) { // base case
        head = head.next;
        myString.append(head.value);   // line 406
        myString.append(", ");         // line 407
        printReverse();                // line 408
    }
    myString = myString.append("]");
    return myString.toString();
}

我收到以下错误:

Exception in thread "main" java.lang.NullPointerException
    at myprog.SLL$Node.access$100(SLL.java:445)

    at myprog.SLL.printReverse(SLL.java:406)

    at myprog.SLL.printReverse(SLL.java:408)

    at myprog.SLL.printReverse(SLL.java:408)

    at myprog.SLL.printReverse(SLL.java:408)

    at myprog.SLL.printReverse(SLL.java:408)

    at myprog.SLLApp.myMethod(SLLApp.java:198)

    at myprog.SLLApp.<init>(SLLApp.java:37)

    at myprog.SLLApp.main(SLLApp.java:26)

我看不出我做错了什么,但我怀疑这可能是我自己调用该方法的方式。谁能建议我可能做错了什么以及如何解决它?

谢谢!

【问题讨论】:

  • 当您执行head = head.next; 时,您应该检查以确保head 不是列表中的最后一个节点。否则head 将是null,因此你得到null pointer exception
  • if (head.next != null) 应该是条件
  • 您的评论 // base case 具有误导性,因为 head != null 中的块正好相反(即递归情况)。
  • @SubhrajyotiMajumder 我按照您的建议进行了尝试,但现在我得到 [4, ] 作为输出。我的 printReverse() 调用正确吗?

标签: java singly-linked-list


【解决方案1】:

你把事情复杂化了。让我们看一下伪代码:

  • 初始节点是头
  • 如果 next 为 null 则打印空白(递归终止条件)
  • 否则递归到下一个节点
  • 然后打印当前节点

在代码中,这变成:

public String printReverse() {
    return printReverse(head); 
}

private String printReverse(Node n) {
    return next == null ? "" : (printReverse(next) + n.value);
}

实际上只有两行代码 - 请参阅 KISS

关于第二个私有方法,对于递归实现的公共方法来说,很常见的做法是将调用 ip 设置为具有适当初始状态的私有递归方法。

【讨论】:

  • 您好,感谢您的回复。我试了一下。我没有 next 变量,假设您的意思是指向 head 之后的元素的变量,我在条件中使用 head.next 进行了尝试,并得到了该行的 StackOverflowError 。有什么建议么?抱歉有这些问题。我没那么有经验。不过感谢您的帮助:)
  • 我在猜测。请发布你的节点类,所以我知道你是如何设置它的。
  • 嗨,没关系,我想我知道该怎么做了。我只是按照你说的方式使用它,并把它改了一点,谢谢!
【解决方案2】:

您不能在方法内声明结果变量。不过,您可以将其作为私有辅助方法的参数。这是一个示例实现:

public String printReverse(Elem elem) {
    return internalReverse(elem, new StringBuilder("[")).append("]").toString();
}
private StringBuilder internalReverse(Elem elem, StringBuilder result) {
    if (elem != null) { // base case
        result.append(internalReverse(elem.next, result));                
        if (result.size() > 1) {
            result.append(", ")
        }            
        result.append(elem);
    }
    return result;
}

【讨论】:

    【解决方案3】:

    Javascript 解决方案。

    function printReverse(list) {
        if (!list) return;
        if (list.next) {
            printReverse(list.next);  
        }
        console.log(list.value);
    }
    

    【讨论】:

    • 我们说的是链接列表而不是列表
    猜你喜欢
    • 2021-11-30
    • 2013-06-02
    • 1970-01-01
    • 2014-11-27
    • 2016-10-08
    • 1970-01-01
    • 2020-01-22
    • 2012-04-08
    • 2021-06-06
    相关资源
    最近更新 更多