函数调用及返回
每次函数调用是一个压入栈的过程,当函数运行结束后,会返回到上一个函数中,弹栈。
举例:
调用情况:main()调用A(),A()调用B(),B()调用C() ---> 递进至边界
返回情况:C()执行完回到B(),B()执行完回到A(),A()执行完回到main() ---> 从边界回归到原问题
- 递归结束条件,递归边界,递归出口
- 递归调用公式,递归链条,对原问题进行划分时,对子问题和原问题处理的逻辑相似性
一些理解
将原问题划归为子问题,这个子问题通常是通往边界的极限情况。
当还没碰到边界条件时,递归不断通向边界情况。(递归不断推进至边界) 当碰到边界条件时,递归不断返回,问题逐一解决,最后回到原问题。(从边界不断回归至原问题)
一些例子
// 输出 0~n
void f(int n){
if(n>0){ // 一直 递进到 边界 f(0)
f(n-1); // 然后 不断回归 到 f(n)
}
cout<<n<<endl;
}
// 数组 从 begin下标 求累加和
int f(int a[],int begin){
if(begin==a.length)return 0; // 一直递进到 begin == a.length
return f(a,begin+1)+a[begin];
}
即 对于 f(a,begin) --> f(a,begin+1)+a[begin]
对于 f(a,begin+1) --> f(a,begin+2)+a[begin+1]
对于 f(a,length-1) --> f(a,length)+a[length-1]
f(a,length) --> 0 出口
采用这样一种思想去递归, 并找到递归边界(出口) , 就能很好解决问题。
一样的思路:
// 求和 至 a [end]
int f(int a[],int end){
if(end==-1)return 0;
return f(a,end-1)+a[end];
}
二分的思路:
//sum(begin下标~end下标),二分求和
int f(int a[],int begin,int end){
if(begin==end)return a[begin]; // 出口
int x=f(a,begin,(begin+end)/2)+f(a,(begin+end)/2+1,end);
return x;
}
对区间进行不断的分割,总会使区间里只有一个元素,也就是说 对每一个子问题, 通过不断的划分,都可求解
底层问题解决掉,不断回归,问题逐层得到解决。
判断字符串是否相等:
bool f(String s1,String s2){
if(s1.length!=s2.length)return false;
if(s1.length==0)return true;
if(s1.charAt(0)!=s2.charAt(0))return false; // 看 首字母 是否相等
return f(s1.substring(1),s2.substring(1)); // 递归 判断子串
}