当前位置:   article > 正文

递归与尾递归的区别与应用_尾递归和普通递归的区别

尾递归和普通递归的区别

一、递归

1.在定义一个过程或函数时,出现调用自己的成分,称为递归
2.递归一般运行时效率都很低,耗时很长;
3.可以将复杂的问题很容易的表示出来,比如汉诺塔的问题,能很好地展现递归的作用;
4.递归在实际问题中都需要一个出口,不能无限进行下去。

二、尾递归

1.如果一个函数中所有递归形式的调用都出现在函数的末尾,则称这个递归函数尾递归
2.递归调用是整个函数体中最后执行的语句且它的返回值不属于表达式的一部分;
3.尾递归只需要保留最后一个函数堆栈,不需要保存很多中间函数的堆栈

特点:在回归过程中不用做任何操作,这个特性很重要,因为大多数现代的编译器会利用这种特点自动生成优化的代码。

代码示例:

递归:

double Fact(int n) {
     if (n == 1) {
         return 1;
     }
     return n * Fact(n - 1);
}
  • 1
  • 2
  • 3
  • 4
  • 5

若n=5,执行次序如下:
Fact(5);
5* Fact(4);
5* (4* Fact(3));
5* (4* (3* Fact(2)));
5* (4* (3* (2* Fact(1))));
5* (4* (3* (2* 1)));
120

可见这种方法空间复杂度为O(n),无论是时间上还是空间上的消耗都很大,极易出现爆栈的情况,进而出现了尾递归的应用

尾递归:

double Fact(int n, double total) {
     if (n == 1) {
         return total;
     }
     return Fact(n - 1, n * total);
}
  • 1
  • 2
  • 3
  • 4
  • 5

若n=5,执行次序如下:
Fact(5,1);
Fact(4,5);
Fact(3,20);
Fact(2,60);
Fact(1,120);
120

由于尾递归只需要保留最后一个函数堆栈,不需要保存很多中间函数的堆栈,所以空间复杂度为O(1),因此大大提高了执行效率

尾递归的应用在时间上没有太大的变化,但空间上的优化很大,有效的避免了爆栈现象,是解题过程中的一种很好的方法。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小小林熬夜学编程/article/detail/116211
推荐阅读
相关标签
  

闽ICP备14008679号