递归是计算机,数学,运筹学等领域经常使用到的最强大解决问题的的方法之一,起主要实思想是把问题划分成一个活多个规模更小的子问题,然后用同样的方法解决规模更小的子问题。ps:那些规模更小之问题应该与原问题保持同一类型,这样才可以用相同的方法来解决。
设计递归的步骤:
(1):找到问题的初始条件(递归出口),当规模小到一定程度时该问题就变得很简单,然后直接求解;
(2):设计一个解决办法让原问题规模逐步变小的变法;
(3):把解决各个小问题得到的解集合起来,及得到原问题的解。
设计递归时的注意事项:
(1):解决方法需使原问题逐步变小,但与原问题保持一致性;
(2):问题规模达到多大时作为递归出口;
(3):随着问题规模的缩小是否都能到达递归出口;
递归算法正确性的证明:
其证明方法很多,但是最常用同时也最方便的是采用数学归纳法,通过循环不变量来逐步测试算法的正确性,当然,如过狮子啊比赛中,没有足够的时间进行证明,可以通过特殊数据测试来快讯验证算法的正确性。
递归的简单应用:
(1):计算2的n次幂,
f(n)=2^n;
当n=1时ff(n)=2^1=2可以作为递归出口,当n>1时f(n)=2 *f(n-1);
因此原问题课表述为:
int f(int n){
if(n==1) return 2;
else return 2* f(n-1) ;
}
Hanoi问题:
问题这里不描述,直接讲述思想,
柱子分别为A,B,C,假设有n块塔片,初始状态n块塔片全部在A上半径冲大到小按从下到上的顺序排列,
要求状态,将n块塔片按A上的顺序在C上排放,
要求:每次只可以移动一片,半径大的必须在半径小的塔片下面,
分析,首先我们借助C将A上的n-1快全部移到B上;
其次将A上最大的那一片(及剩下的那一片)移到C上,
然后我们在将n-1个从B借助A搬到C;任务完成
代码如下:
void Hanoi(int n, char A, char B, char C){
if(n==1) printf("move %d from %c to %c", n ,A,C);//只有一片,直接移动,递归出口
else{
Hanoi(n-1,A,C,B);//借助C将n-1片由A移到B
printf("move %d from %c to %c", n ,A,C);
Hanoi(n-1,B,A,C);
}
}