递归的概念
递归是指由一种(或多种)简单的基本情况定义的一类对象或方法,并规定其他所有情况都能被还原为其他基本情况。递归使用到大量堆、栈空间,降低算法效率费时费内存。
递归一般可以解决以下三大类问题:
1、数据是按递归方式定义的,例如斐波拉切数列、阶乘、汉诺塔问题等
2、问题解决可以按递归方式实现,例如回溯
3、数据的结构形式是按递归定义的,例如树的遍历、图的搜索等。
用递归方法解决问题的过程中,递归函数的内部执行过程大致分为三步:
1、运行开始时为递归调用建立一个工作栈,其结构包括实参、局部变量和返回地址;
2、每次执行递归调用前,把递归函数的实参和局部变量的当前的值以及调用后的返回地址压栈;
3、每次递归调用结束后,将栈顶元素出栈,使相应的实参和局部变量恢复为调用前的值,然后转向返回地址指定的位置继续执行。
实例1:
下述代码给出用非递归和递归的方法输出n个自然数,从中体会递归和非递归思想的不同之处。
#include <iostream>
using namespace std;
void PRINT_A(int n) //非递归算法
{
int i;
for (i = 1; i < n; i++)
{
cout << i << " ";
}
cout << endl;
return;
}
void PRINT_B(int n) //递归算法
{
if (n == 0)
return;
else
{
PRINT_B(n-1);
cout << n <<" ";
}
return;
}
int main()
{
int j;
cin>>j;
if (j == 1)
{
PRINT_A(10);
}
else if (j == 2)
{
PRINT_B(10);
cout << endl;
}
return 0;
}
执行结果:
hong@debian:/mnt/hgfs/linux/cpp/recursion$ ./main
1
1 2 3 4 5 6 7 8 9
hong@debian:/mnt/hgfs/linux/cpp/recursion$ ./main
2
1 2 3 4 5 6 7 8 9 10
实例2:Fibonacci数列
无穷数列1,1,2,3,5,8,13,21,34,55,…被称为Fibonacci数列;它的递归公式:
n = 0 F(n) = 1
n = 1 F(n) = 1
n > 1 F(n) = F(n-1) + F(n-2)
n=0和n=1是递归函数的边界条件(递归出口),n>1为递归函数的递归方程。
#include <iostream>
using namespace std;
int fibonacci(int n);
int main()
{
int n, result;
cin >> n;
result = fibonacci(n);
cout << result << endl;
return 0;
}
int fibonacci(int n)
{
int goal;
if (n == 1 || n ==2)
{
goal =1;
}
else
{
goal = fibonacci(n -1) + fibonacci(n - 2);
}
return goal;
}
根据递归方程可以画出一个下面的树状图,把问题分解成一个个子问题,子问题合并成一个复杂的问题。
执行结果:
hong@debian:/mnt/hgfs/linux/cpp/recursion$ ./main
8
21
hong@debian:/mnt/hgfs/linux/cpp/recursion$ ./main
10
55