前沿
递归的思维是软件思维的根本思维之一,在树和图下面,简直全是用递归来实现的。计算机特地适宜用递归的思维来解决问题,然而咱们人类用递归的思维来思考问题就会感到非常困扰。接下来咱们一起探索递归吧。
定义
一个函数本人间接或者间接调用本人
注 :一个函数调用另外一个函数和他调用本人都是截然不同的。
递归满足的三个条件:
- 递归必须有一个明确的终止条件
- 该函数解决的数据规模必须在递加
- 这个转化必须时可解的
函数的调用
当在一个函数的运行期间调用另外一个函数时,在运行被调用函数之前,零碎须要实现三件事
- 将所有的理论参数,返回地址等信息传递给被调用函数。
- 为被调用函数的局部变量(也包含形参)调配存储空间。
- 将管制转移到被调用函数的入口。
从被调函数返回主调函数之前,零碎也要实现三件事
- 保留被调函数的返回后果
- 开释被调函数所占的存储空间
- 按照被调函数保留的返回地址将管制转移到调用函数
当有多个函数互相调用时,依照“后调用先返回”的准则
上诉函数之间信息传递和管制转移必须借助“栈”来实现,即零碎将整个程序运行所需的数据空间安顿在一个栈中,每当调用一个函数时,将在栈顶调配一个存储区,进行压栈操作,每当一个函数退出时,就开释它的存储区,就进行出栈操作,以后运行的函数永远都在栈顶地位。
算法
咱们来看一题比拟经典的面试题,大家能够本人猜想下运算后果
#include <iostream>
#include <cstdlib>
int f(int num)
{printf("%d\n", num);
if (num <= 1) {return 1;}
f(num-1);
printf("%d\n", num);
return 0;
}
int main()
{f(3);
return 0;
}
这道题目后果会是什么呢?他到底是怎么调用的呢?
我来画个调用图
咱们关注红色的调用箭头
- 首先运行主函数的 f(3)
- 而后调用 int f(3) 打印出 3
- 而后调用 int f(2) 打印出 2
- 而后调用 int f(1) 打印出 1,而后满足条件 return 1;完结 int (f1)
- 之后回到 int f(2) 打印出 2
- 之后回到 int f(3) 打印出 3
- 最初回到主函数,程序完结
所以最初打印的数是 3 2 1 2 3
致谢
感激你看完这篇文章,有什么不对的中央欢送指出,谢谢????