递归的基本思想就是:把问题分解成为规模更小的、具有与原问题有着相同解法的问题。
(Recursion is the process of repeating items in a self-similar way.)
在编程中,最常用的例子就是斐波那契数列的求解,我在下列中用了4种方法,加深对递归的理解。
#include <iostream>
using namespace std;
//递归
//优点:代码及其简洁,易懂(如果理解递归的话)
//缺点:执行效率低,如果递归层数过多,会导致爆栈
int fibonacci_recursion(int num)
{
return num<2 ? 1: (fibonacci_recursion(num - 1) + fibonacci_recursion(num - 2)) ;
}
void test_fibonacci_recursion(int n)
{
int result = fibonacci_recursion(n);
cout<<"The result of fibonacci: "<<result<<endl;
}
//递归:缓存中间数据
//优点:以空间换时间,执行效率高
//缺点:额外的内存开销,数据越多需要的内存越多
int fibonacci_cache(int num, int *mem)
{
if (mem[num] == -1)
{
mem[num] = fibonacci_cache(num - 1, mem) + fibonacci_cache(num - 2, mem);
}
return mem[num];
}
void test_fibonacci_cache(int n)
{
//将所有的数据都缓存到mem中,并设置标志位
int *mem = (int *)malloc(sizeof(int) * n);
mem[0] = mem[1] = 1;
for (int i = 2; i <= n; i++)
mem[i] = -1;
int result = fibonacci_cache(n, mem);
cout<<"The result of fibonacci: "<<result<<endl;
free(mem);
}
//尾递归
//参数fib2实质上在做累加工作,很容易转化成迭代,见fibonacci_loop()
int fibonacci_tail(int num,int fib1,int fib2)
{
return num<2 ? fib2: (fibonacci_tail(num-1,fib2,fib1+fib2)) ;
}
void test_fibonacci_tail(int n )
{
int result = fibonacci_tail(n, 1, 1);
cout<<"The result of fibonacci: "<<result<<endl;
}
//迭代
//优点:执行效率高,容易理解
//缺点:当不知道“层次/深度”的时候(即num),循环次数是不确定的
int fibonacci_loop(int num,int fib1,int fib2)
{
int tmp;
for(int i = 0; i<num-1; i++)
{
tmp = fib1+fib2;
fib1 = fib2;
fib2 = tmp;
}
return fib2;
}
void test_fibonacci_loop(int n )
{
int result = fibonacci_loop(n, 1, 1);
cout<<"The result of fibonacci: "<<result<<endl;
}
int main()
{
int n = 10;
cout<<"*********************test_fibonacci_recursion************************"<<endl;
test_fibonacci_recursion(n);
cout<<"*********************test_fibonacci_cache****************************"<<endl;
test_fibonacci_cache(n);
cout<<"*********************test_fibonacci_tail*****************************"<<endl;
test_fibonacci_tail(n);
cout<<"*********************test_fibonacci_loop*****************************"<<endl;
test_fibonacci_loop(n);
}