递归

292 阅读2分钟

函数调用及返回

每次函数调用是一个压入栈的过程,当函数运行结束后,会返回到上一个函数中,弹栈。

举例:
调用情况: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));		// 递归 判断子串 
}