递归算法实际上是一种分而治之的方法,它把复杂问题分解为简单问题来求解。递归的特点包括:递归过程简洁、易编、易懂;递归过程效率低、重复计算多。
考虑递归的执行效率低,可以尝试将递归过程转换为非递归过程。本文就是来探讨怎么转换的。
将递归算法转换为非递归算法有两种方法,一种是直接求值(迭代/循环),不需要回溯;另一种是不能直接求值,需要回溯。前者使用一些变量保存中间结果,称为直接转换法;后者使用栈保存中间结果,称为间接转换法,下面分别讨论这两种方法。
一、直接转换法
直接转换法通常用来消除尾递归和单向递归,将递归结构用循环结构来替代。
1.单向递归
简单的说是指递归的过程总是朝着一个方向进行,如果函数1调用了函数2,而函数2又调用了函数1,则这种情况不属于单向递归。斐波那契数列(单向递归)的递归求解可转用一个迭代法实现。
斐波那契数列的递归求解:
int Fib(int n) {
if(n <= 1) return n;
else return Fib(n - 1) + Fib(n - 2);
}
转换为迭代求解过程:
int Fib(int n) {
if(n <= 1) return n;
int twoBack = 0;
int oneBack = 1;
int cur;
for(int i = 2;i < = n; i++) {
cur = twoBack + oneBack;
twoBack = oneBack;
oneBack = cur;
}
return cur;
}
2.尾递归
是以递归调用结尾的函数,是单向递归的特例。它的递归调用语句只有一个,而且是放在过程的最后。当递归调用返回时,返回到上一层递归调用语句的下一语句,而这个位置正好是程序的结尾,因此递归工作栈中可以不保存返回地址;除了返回值和引用值外,其他参数和局部变量都不再需要,因此可以不用栈,直接采用循环写出非递归过程。
阶乘函数就不是一