递归
在学习数据结构中,这是一个非常重要的知识
递归就是函数直接或间接的调用本身。
下面给出几个递归的经典的例子
1.从1+2+3+4+...+n
#include<stdio.h>
int f(int n);
int main()
{
int n;
scanf("%d",&n);
printf("%d\n",f(n));
return 0;
}
int f(int n)
{
if(n==1)
return 1;
else
return f(n-1)+n;
}
2.汉诺塔
#include<stdio.h>
int f(int n);
int main()
{
int n;
scanf("%d",&n);
printf("%d\n",f(n));
return 0;
}
int f(int n)
{
if(n==1)
return 1;
else
return 2*f(n-1)+1;
}
经过以上例子,我们可以知道递归必须需要满足两个条件:
1.需要递归终止的条件
2.在实现递归时,需要朝着规模减小的情况进行下去。
以上我们仅仅是表象的了解了递归,递归的深层次含义是什么呢?
在计算机中他是怎样实现的呢?
递归是这样 实现的,在调用自己时,系统为函数分配一个内存栈区。
函数调用过程如下:
函数调用
调用条件:假设有A,B两个函数, A函数调用B函数,即A函数为调用函数,B函数为被调用函数。
1.A函数将函数中的实参以及执行下一条语句的地址传递给B函数中保存。
2.为B函数中的局部变量(形参)分配内存空间。
3.CPU的控制机制转移至B函数的入口
在这时,开始执行B函数的运行过程。
执行完B函数之后在返回A函数之前,需要完成以下三点。
1.保存B函数的执行结果
2.释放为B函数分配的内存。
3.将B函数中保存的A函数中需要执行下一条操作语句的地址控制转移到A函数中
以上就是两个函数的调用过程。
假如有多个函数调用的时侯,我们可以这样理解。
在计算机内部,当一个程序运行的时候,是以栈的方式进行存储。调用函数与被调用函数处于栈内部。
未调用函数与已经结束的调用函数位于栈底。始终 保持被调用函数处于栈顶位置。反复如此。
调用自身与调用别人并没有区别。