浅析线性递归和尾递归

1. 定义

线性递归:也即是普通递归,单向递归,线性递归函数的最后一步操作不是递归操作,而是其他的操作。当数据量很大的时候,会造成栈溢出,这是因为,在每次递归调用时,递归函数中的参数,局部变量等都要保存在栈中,如果数据量很大的话,便可能会溢出。
尾递归:也即是线性迭代,尾递归函数的最后一步操作是递归,也即在进行递归之前,把全部的操作先执行完,这样的好处是,不用花费大量的栈空间来保存上次递归中的参数、局部变量等,这是因为上次递归操作结束后,已经将之前的数据计算出来,传递给当前的递归函数,这样上次递归中的局部变量和参数等就会被删除,释放空间,从而不会造成栈溢出。但是很多编译器并没有自动对尾递归优化的功能,也即当编译器判断出当前所执行的操作是递归操作时,不会理会它究竟是线性递归还是尾递归,这样也就不会删除掉之前的局部变量和参数等。另外,尾部递归一般都可转化为循环语句。
一般来说,线性递归和尾递归的时间复杂度相差不大(当然也有例外情况,比如斐波拉契数列,这是因为其线性递归的实现,产生了大量冗余的计算,它的时间复杂度为指数级,而其尾递归的实现只需要线性级别的时间复杂度),但尾递归的空间复杂度比较小(这是在假定尾递归被优化的前提下),线性递归容易理解,尾部递归性能比较好。

2. 示例

以下举出两个例子:
n的阶乘的两种递归实现方式,前者为线性递归,后者为尾递归,后者在计算时,传入的参数a为1,即执行facttsail(n,1),很明显,后者很容易转化为循环语句。

public int fact(int n) { if(n<=0) return 0; else if(n==0 || n==1) return 1; else return n*fact(n-1); } public int factail(int n,int a) { if(n<0) return 0; else if(n==0) return 1; else if(n==1) return a; else return factail(n-1,n*a); }

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

斐波拉契数列的两种递归实现方式:
1、线性递归实现(这种方法很直观,很容易理解,但是效率很低,应尽量避免,不符合递归调用时的合成效益准测)

public static int FibonacciRecursively(int n){
  if (n < 2)
      return n;
  else
      return FibonacciRecursively(n - 1) + FibonacciRecursively(n - 2);
 }    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

2、尾递归实现,这里需要提供两个累加器:acc1和acc2,调用时acc1赋值0,acc2赋值1,很明显,该方法也很容易转化为循环语句

public static int FibonacciTailRecursively(int n, int acc1, int acc2) { if (n == 0) return acc1; else return FibonacciTailRecursively(n - 1, acc2, acc1 + acc2); }

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
(0)

相关推荐

  • 时间复杂度分析,这个很多人都不知道,更别谈会了!

    时间复杂度 请原谅我也是一个标题党! 关于时间复杂度和空间复杂度分析的文章其实不少,但大多数都充斥着复杂的数学计算,让很多读者感到困惑,我就不跟大家扯皮了,关于什么是渐近分析.最坏时间复杂度.平均时间 ...

  • 什么是递归函数?

    FlyWine2018-02-21 09:42:10 44910 收藏 120 分类专栏:C++文章标签:递归函数c++递归函数什么是递归 版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA ...

  • 《缠论之走势类型的划分与级别递归手画浅析》

    <第23课,市场与人生>:说了这么多技术上的问题,暂且停一期,说说技术外的事情.技术只是最粗浅的东西,同样的技术,在纯技术的层面,在不同人的理解中,只要能正确地理解里面的逻辑关系,把握是没 ...

  • ​浅析农贸市场设计改造与动态线路规划的重要性

    浅析农贸市场设计改造与动态线路规划的重要性 现代农贸市场的日常运作,动态线路设计必须保持稳定发展的首要因素.完善合理的动态线路规划,不仅能反映进入市场时的客货供应情况,而且对引导顾客的购物趋势也有很大 ...

  • 浅析抗体偶联药物的理想抗原靶点应该具有哪些特征

    近年来抗体偶联药物(ADC)已经成为抗肿瘤药物研发的热点,可以将细胞毒药物直接运输到癌细胞发挥杀伤作用.合适的抗原靶点.高度特异性的抗体.理想的偶联子和高效的偶联药物的选择是一个成功的ADC药物需要具 ...

  • 浅析人工智能的发展方向

    众所周知人工智能现如今正在高速发展,并且深入人们的生活和工作中,这不仅对人工的生活和工作提供了便利,同时也对人们未来的生活产生了影响.那么未来人工智能的发展方向主要在哪些方面? 一是在治疗方面,开发出 ...

  • 后疫情时代,互联网医疗发展模式及特点浅析

       近年来,在医改.分级诊疗.消费升级.老龄化.大数据.AI等多种因素叠加影响下,互联网医疗产业迅速发展.随着移动互联网技术与医疗服务加速融合,互联网医疗市场呈现出百花齐放之态势. 近一年多由于疫情 ...

  • 浅析中药外治法的诊疗思路

    中药外治法是中医治疗学的重要组成部,是以中医基础理论为指导,包括中草药制剂,除口服药外,施于皮肤.孔窍.腧穴及病变局部等各种独特治疗方法,目前种类已达150余种,既丰富又实用. 中药外治法,具有&qu ...

  • TDMA 噪声问题浅析

    时分多址(Time division multiple access,缩写:TDMA) 是一种为实现共享传输介质或者网络的通信技术. 在移动通信中GSM 2G网络中的标准制式.用在EGSM,GSM,D ...

  • 20世纪西方抽象艺术:浅析抽象绘画的历史发展进程和审美特征

    在当代很多艺术展览馆上,不少人都会遇到一些令人"尴尬"的艺术作品,他们常常歪歪扭扭,画有让人难以理解的涂鸦和方形,这个时候,很多人并没有透彻的理解这些奇怪的画,不少人坚信这些画应该 ...

  • 浅析古诗中的床

    现在一提到"床"我们便会想到它是一种供人躺在上面睡觉的家具.但在古典诗文中它的意义却非常丰富.复杂.概括起来主要有以下几类情况. 一.供人睡卧的家具 相当于现代汉语中"床 ...