递归和尾递归

作者: zhangman523 | 来源:发表于2019-06-19 11:17 被阅读58次

原文

递归原理

递归是一种解决问题的有效方法,在递归过程中,函数将自身作为子例程调用

你可能想知道如何实现调用自身的函数。诀窍在于,每当递归函数调用自身时,它都会将给定的问题拆解为子问题。递归调用继续进行,直到到子问题无需进一步递归就可以解决的地步。

为了确保递归函数不会导致无限循环,它应具有以下属性:

  • 一个简单的基本案例(basic case)(或一些案例) —— 能够不使用递归来产生答案的终止方案。
  • 一组规则,也称作递推关系(recurrence relation),可将所有其他情况拆分到基本案例。

注意,函数可能会有多个位置进行自我调用。

尾递归

尾递归函数是递归函数的一种,其中递归调用是递归函数中的最后一条指令。并且在函数中应该只有一次递归调用。

尾递归的好处是,它可以避免递归调用期间栈空间开销的累积,因为系统可以为每个递归调用重用栈中的固定空间。

我们来看下面的例子:

public class Main {

  private static int helper_non_tail_recursion(int start, int [] ls) {
    if (start >= ls.length) {
      return 0;
    }
    // 不是尾递归,因为它在返回递归调用后进行了一些计算。
    return ls[start] + helper_non_tail_recursion(start+1, ls);
  }

  public static int sum_non_tail_recursion(int [] ls) {
    if (ls == null || ls.length == 0) {
      return 0;
    }
    return helper_non_tail_recursion(0, ls);
  }

  //---------------------------------------------

  private static int helper_tail_recursion(int start, int [] ls, int acc) {
    if (start >= ls.length) {
      return acc;
    }
    // 这是一个尾递归,因为最后的指令是递归调用。
    return helper_tail_recursion(start+1, ls, acc+ls[start]);
  }

  public static int sum_tail_recursion(int [] ls) {
    if (ls == null || ls.length == 0) {
      return 0;
    }
    return helper_tail_recursion(0, ls, 0);
  }
}

请注意,在尾递归的情况下,一旦从递归调用返回,我们也会立即返回,因此我们可以跳过整个递归调用返回链,直接返回到原始调用方。这意味着我们根本不需要所有递归调用的调用栈,这为我们节省了空间。

尾递归函数可以作为非尾递归函数来执行,也就是说,带有调用栈并不会对结果造成影响。通常,编译器会识别尾递归模式,并优化其执行。然而,并不是所有的编程语言都支持这种优化,比如 CC++ 支持尾递归函数的优化。另一方面,JavaPython 不支持尾递归优化。

相关文章

  • 递归和尾递归

    作者:匿名用户 链接:https://www.zhihu.com/question/20761771/answer...

  • 递归和尾递归

    递归(recursion) 递归指函数体中直接或间接调用自身的一种方法,递归的解决思路通常是把一个大问题转化为许多...

  • 递归和尾递归

    原文 递归原理 递归是一种解决问题的有效方法,在递归过程中,函数将自身作为子例程调用 你可能想知道如何实现调用自身...

  • Kotlin语言(九):特性

    1、尾递归优化 尾递归:函数在调用自己之后没有再执行其他任何操作就是尾递归 尾递归优化的原理就是将递归转换成迭代,...

  • python学习

    1:尾递归 解决递归调用栈溢出的方法是通过尾递归优化,事实上尾递归和循环的效果是一样的,所以,把循环看成是一种特殊...

  • 递归&尾递归

    调用栈的特点,先进后出, FILO, 场景还原。 递归 有栈溢出的可能 stack overflow 尾递归 编译...

  • C++ 递归算法

    递归算法,尾递归算法求阶乘!

  • 递归调用优化

    尾递归优化 函数调用自身,称为递归。如果尾调用自身,就称为尾递归。 递归非常耗费内存,因为需要同时保存成千上百个调...

  • 25.尾递归优化

    1.代码如下: 只有尾递归才能优化 1.需要将递归转化为尾递归2.加上关键字tailrec 2.尾递归的原理,看编...

  • 尾调用优化

    尾调用优化 尾递归 正常递归 尾递归 改写以上代码,使其只有一个参数: 总结一下,递归本质上是一种循环操作。纯粹的...

网友评论

    本文标题:递归和尾递归

    本文链接:https://www.haomeiwen.com/subject/wguhqctx.html