在递归函数中初始化变量

时间:2013-09-17 17:08:08

标签: java variables recursion linked-list initialization

我正在创建一个递归函数,它没有参数来获取链表的长度。

public int lengthHelper() {
    if (first == null) {
        return 0;
    } else {
        first = first.next;
        return 1 + length();
    }
}

问题在于,通过使用first = first.next,我将首先破坏,首先是我的标题。所以我想先在函数内复制(而不是我丑陋的包装器脚本),但递归使得这很麻烦。知道怎么办吗?

这是包装顺便说一句,我想删除它:

public int length() {
    Node temp = copy(first);
    int output = this.lengthHelper();
    first = copy(temp);
    return output;
}

我有这些限制的原因是因为这是基于作业的个人挑战。递归+包装就足够了,但自从我一直在想是否有可能以更清洁的方式解决它。

3 个答案:

答案 0 :(得分:3)

如果我理解正确first是递归数据结构Node,并且在非递归容器类List(例如)中,则需要定义递归方法(不带参数) )。

然后解决方案是在List中有一个方法,它产生一个新的尾部/休息列表,没有first。下面我假设一个带有Node的构造函数。

class Node { }
public class List {
    Node first;

    public int length() {
        if (first == null) {
            return 0;
        } else {
            List tail = new List(first.next);
            return 1 + tail.length();
        }
    }

答案 1 :(得分:2)

这是一个非常人为的要求。 :)但是如何将first存储在本地堆栈框架中,然后在返回之前将其恢复?

这听起来像是一个家庭作业问题,所以也许我不应该把完整的答案说出来。但它基本上是这样的:

  • 创建一个局部变量来存储当前值first
  • 更新first,从而打破了列表(正如您所指出的那样)
  • 递归,并将该递归的结果保存在第二个局部变量
  • 使用第一个本地变量来恢复first
  • 返回第二个局部变量的结果

如果您碰巧在流程中遇到异常(例如堆栈溢出),请尝试以不会破坏列表的方式执行此操作。提示:try-finally

答案 2 :(得分:1)

这样做没有干净的方法。我推荐这样的东西:

public int length() {
    return computeLength(this.first);
}
private int computeLength(Node node) {
    if (node == null) return 0;
    return 1 + computeLength(node.next);
}