呕心沥血的递归
递归的概念
既然是递归,先看看递归的概念,概念来源于网络
在数学与计算机科学中,递归(Recursion)是指在函数的定义中使用函数自身的方法。实际上,递归,顾名思义,其包含了两个意思:递 和 归,这正是递归思想的精华所在。
解释一下上面的意思:所谓递和归,就是在递的时候,将现有的问题分散成与原问题相同的小问题;这些问题可以使用原有的问题进行解析求解;
举个例子:就好比往返跨栏接力赛,每个人跨一个栏传递接力棒,到终点后,不再往远处走,这个过程就叫做递,到终点后,往回返,这个就是归,这个就是一个递归的往返过程;
递归三要素
一、定义函数
首先,需要定义函数,知道函数是用来干嘛的,然后根据后面两要素进行编写代码
比如:void Fibonacci(int n)
定义斐波那契数列
二、找出函数的等价关系式
这个其实更准确的说是一种归纳和找规律;我们需要把问题归结成一个等价关系式
比如:斐波那契等价关系式:f(n) = f(n-1)+f(n-2)
三、寻找递归结束条件
所谓递归,就是会在函数内部代码中,调用这个函数本身,所以,我们必须要找出递归的结束条件,不然的话,会一直调用自己,进入无线循环之中。也就是说,我们需要找出当参数为什么时,递归结束,之后直接把结果返回,请注意,这个时候我们必须能根据这个参数的值,能够直接知道函数的结果是什么。
比如:当输入n,当n==1时,返回1,return 1;
递归的本质
当递归调用时每次调用自己时可以看做是压栈过程,当递归条件满足结束时,递归一级一级的返回时可以看做是出栈的过程;(其实就是不满足条件入栈,满足条件出栈的操作)
这个我们用一个例子来说明下
案例一
最多用的斐波那契数列来吧说明
斐波那契数列(Fibonacci sequence),又称黄金分割数列、因数学家列昂纳多·斐波那契(Leonardoda Fibonacci)以兔子繁殖为例子而引入,故又称为“兔子数列”,指的是这样一个数列:1、1、2、3、5、8、13、21、34、……n
这里我们先分析一下:第n项是什么:
n=1
f(1) = 1
f(2) = 1
f(3) = 2 = f(1)+f(2)
f(4) = 3 = f(3)+f(2)
...
f(n) = f(n-1) + f(n-2)
所以,斐波那契数列就是f(n) = f(n-1) + f(n-2)
代码:
//递归第一要素,定义函数
int Fibonacci(int n)
{
//递归第二要素,知道结束条件
if (n == 1 || n == 2)
{
return 1;
}
return Fibonacci(n - 1) + Fibonacci(n - 2);
}
我们分析一下递归的过程
假设输入的n=4
使用本代码测试:
#include <iostream>
using namespace std;
//递归第一要素,定义函数
int Fibonacci(int n)
{
//递归第二要素,知道结束条件
if (n == 1 || n == 2)
{
return 1;
}
cout << "n:"<<n << endl;
int f1 = Fibonacci(n - 1);
int f2 = Fibonacci(n - 2);
cout << "f2" << endl;
return f1+f2;
}
int main()
{
int res = Fibonacci(4);
cout << "res:" << res << endl;
return 0;
}
按照步骤进行分析:
第一步:n=4,不满足终止条件,入栈,此时栈(从底到顶)4,执行函数Fibonacci(n - 1)
第二步:n=3,不满足终止条件,入栈,此时栈(从底到顶)4,3,执行函数Fibonacci(n - 1)
第三步:n=2,满足终止条件,返回1,中断函数f1的执行,切换函数Fibonacci(n - 2)
第四步:栈顶元素是3,出栈,此时n-2 = 1,所以n=1满足条件,本次递归完成,返回f1+f2赋值给f1,所以直接执行f2函数;
第五步:栈顶元素为4,出栈,此时n-2 = 2;满足条件,此时f1为1,递归完成,返回函数f1+f2=2+1=3;
案例二(双重递归)
我们在来做一个双重递归,分析一下出栈和入栈的过程
代码:
#include <iostream>
using namespace std;
void test(int n)
{
if (n > 0)
{
//test1
test(n - 1);
//test2
test(n - 10);
}
cout << "n=" << n << endl;
}
int main()
{
test(5);
return 0;
}
结果:
n=0
n=-9
n=1
n=-8
n=2
n=-7
n=3
n=-6
n=4
n=-5
n=5
接下来,一步一步分析:
第一步:执行函数test(n - 1),入栈数据,执行完该函数之后,栈中数据为(从底到顶):5,4,3,2,1
第二步:当n=0的时候,不符合条件,出栈,此时,搁置test(n - 1)的入栈,test(n - 10)开始入栈;
第三步:取栈顶元素n=1,注意此时并未出栈,元素还在栈中,n=1,执行test(n - 10),n不符合条件,打印n=1-10=-9,然后n再出栈,所有会再次打印n=1;
第四步:按照第四步的顺序,依次进行循环出栈,即为上述的结果,也是双重递归的执行顺序;
总结
以上就是递归的一些概念以及执行顺序,这里做一个回顾和温习;希望能看到的这篇文章的大家可以对这个有更好的理解;
往期精彩汇总
冰冻三尺,非一日之寒,水滴石穿,非一日之功,愿我们一起加油努力~
本文使用 mdnice 排版