Java中的迭代与递归

1.递归

考虑阶乘函数: n!=n*(n-1)*(n-2)*...*1
有许多计算阶乘的方法。一种方法是n!等于n *(n-1)!。因此,该程序可以直接编写为:

程序1:

int factorial (int n) {
    if (n == 1) {
        return 1;
    } else {
        return n*factorial(n-1);
    }
}

为了运行该程序,计算机需要建立一个乘法链:factorial(n)→factorial(n-1)→factorial(n-2)→…→factorial(1)。因此,计算机必须跟踪以后要执行的乘法。这种类型的程序具有一系列操作,称为递归。递归可以进一步分为线性和树型递归。当跟踪操作链所需的信息量随输入线性增长时,递归称为线性递归。n的计算!之所以如此,是因为所需时间随n线性增长。当信息量随输入量呈指数增长时,会发生另一种类型的递归树递归。但是我们将在这里不加讨论,然后不久再返回。

2.迭代

关于计算阶乘的不同观点是,首先将1乘以2,然后将结果乘以3,然后乘以4,依此类推,直到n。更正式地讲,程序可以使用从1到n计数的计数器,并同时计算乘积,直到计数器超过n。因此,程序可以写成:

程式2:

int factorial (int n) {
    int product = 1;
    for(int i=2; i<n; i++) {
        product *= i;
    }
    return product;
}

与程序2相比,该程序没有建立乘法链。在每个步骤中,计算机仅需要跟踪产品和i的当前值。这种程序称为迭代,其状态可以由固定数量的变量,描述变量应如何更新的固定规则以及指定过程终止条件的最终测试来概括。与递归相同,当所需时间随输入线性增长时,我们将迭代称为线性递归。

3.递归与迭代

比较这两个过程,我们可以发现它们看起来几乎相同,特别是在数学函数方面。它们都需要与n成正比的多个步骤才能计算n!。另一方面,当我们考虑这两个程序的运行过程时,它们的发展完全不同。

在迭代情况下,程序变量提供状态的完整描述。如果我们在中间停止了计算,则只需将所有变量提供给计算机即可继续进行计算。但是,在递归过程中,信息由计算机维护,因此被“隐藏”到程序中。这使得停止程序后几乎无法恢复程序。

4.树递归

如上所述,当信息量随输入量呈指数增长时,会发生树递归。例如,考虑如下定义的斐波那契数列:
在这里插入图片描述
根据定义,斐波那契数具有以下顺序,其中每个数是前两个数的和: 0, 1, 1, 2, 3, 5, 8, 13, 21, ...

递归程序可以立即编写为:

程式3:

int fib (int n) {
    if (n == 0) {
        return 0;
    } else if (n == 1) {
        return 1;
    } else {
        return fib(n-1) + fib(n-2);
    }
}

因此,要计算fib(5),程序将计算fib(4)和fib(3)。要计算fib(4),它会计算fib(3)和fib(2)。注意,fib过程在最后一行调用了两次。从定义和程序中可以获得两个观察结果:

第i个斐波那契数Fib(i)等于phi(i)/ rootsquare(5),四舍五入到最接近的整数,这表明斐波那契数呈指数增长。
这是一种计算斐波纳契数的不好方法,因为它会进行冗余计算。计算此过程的运行时间超出了本文的范围,但是可以在算法书籍中轻松找到这一点,即O(phi(n))。因此,程序花费的时间随输入量呈指数增长。
另一方面,我们也可以以迭代方式编写程序来计算斐波那契数。程序4是线性迭代。计划3和计划4所需的时间差异很大,即使是小额投入也是如此。

程序4:

int fib (int n) {
    int fib = 0;
    int a = 1;
    for(int i=0; i<n; i++) {
       fib = fib + a;
       a = fib;
    }
    return fib;
}

但是,不应认为树递归程序没有用。当我们考虑在分层数据结构而不是数字上运行的程序时,树递归是一种自然而强大的工具。它可以帮助我们理解和设计程序。与程序3和4相比,我们可以很容易地看出,程序3更简单,即使效率较低。之后,我们很可能可以将程序重新设计为迭代方式。
在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值