赞
踩
1.在定义一个过程或函数时,出现调用自己的成分,称为递归;
2.递归一般运行时效率都很低,耗时很长;
3.可以将复杂的问题很容易的表示出来,比如汉诺塔的问题,能很好地展现递归的作用;
4.递归在实际问题中都需要一个出口,不能无限进行下去。
1.如果一个函数中所有递归形式的调用都出现在函数的末尾,则称这个递归函数是尾递归;
2.递归调用是整个函数体中最后执行的语句且它的返回值不属于表达式的一部分;
3.尾递归只需要保留最后一个函数堆栈,不需要保存很多中间函数的堆栈
特点:在回归过程中不用做任何操作,这个特性很重要,因为大多数现代的编译器会利用这种特点自动生成优化的代码。
递归:
double Fact(int n) {
if (n == 1) {
return 1;
}
return n * Fact(n - 1);
}
若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);
}
若n=5,执行次序如下:
Fact(5,1);
Fact(4,5);
Fact(3,20);
Fact(2,60);
Fact(1,120);
120
由于尾递归只需要保留最后一个函数堆栈,不需要保存很多中间函数的堆栈,所以空间复杂度为O(1),因此大大提高了执行效率
尾递归的应用在时间上没有太大的变化,但空间上的优化很大,有效的避免了爆栈现象,是解题过程中的一种很好的方法。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。