博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
递归和尾递归
阅读量:6265 次
发布时间:2019-06-22

本文共 1494 字,大约阅读时间需要 4 分钟。

递归原理

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

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

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

  • 一个简单的基本案例(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://juejin.im/post/5d09a8bae51d45776031b00c

你可能感兴趣的文章
android 中文api (84) —— TrafficStats
查看>>
【Android】不使用WebView来执行Javascript脚本(Rhino)
查看>>
[LeetCode] Longest Repeating Character Replacement 最长重复字符置换
查看>>
9.5. FAQ
查看>>
Oracle数据库 中的基础的一些语法结构
查看>>
HDU 1213 How Many Tables
查看>>
第 23 章 devel
查看>>
(转) The care and maintenance of your adviser
查看>>
【读书】领导力的5个层次-巅峰
查看>>
【阿里云MVP月度分享】基于PAI平台和Pokemon数据集判断精灵是否为极品精灵
查看>>
第 144 章 Sniffer
查看>>
第 47 章 Apache Tomcat
查看>>
设计模式之禅之设计模式-观察者模式
查看>>
Android 友盟分享躺过的几个坑,大坑,坑爹啊
查看>>
Java解析XML与生成XML文件
查看>>
Head First设计模式之备忘录模式
查看>>
UML九种图
查看>>
AOP的原理和实例
查看>>
通过SQL解读财富的分配(二)
查看>>
复杂SQL性能优化的剖析(一)(r11笔记第36天)
查看>>