模板:
1** name(2参数)
{
3.返回条件
4.问题拆解…
}
所谓递归,无非是将一个问题拆解为一个或多个小问题并且给出所有递归出口的情况(5)
上面标注出的1,2,3,4,5每一个都有可能是当前问题的难点,如何解决,就需要多多看题解,多多写题了.
eg:斐波那契数列
int fib(int n)
{
if(n==1||n==2)
return 1;
return fib(n-1)+fib(n-2);
}
我们就这个题目和详细看一下:
1.返回值:我们求的是斐波那契的数列和,那么返回值为int
2.参数:***当前***参数为N时,问题可以分解为前N-1项和前N-2项的和的累加,所以,一个参数N就够了
3.返回条件,这里特别要注意,问题的子规模为N-1和N-2,那么我们应该保证N-2大于等于0,从第零项开始算起,数列依次为1 1 2 3 5 8 13…
所以终止条件就是当递归到第一个’1’,或第二个’1’时结束.此时返回1
4.问题拆解:其实三和四的顺序不是固定的,更多的是考虑一种情况的拆解,拆解为子问题后再判断终止条件,至于怎么拆解,我们可以通过手动模拟和积累经验慢慢来分解.手动模拟就是读懂题目并能够充分挖掘题目条件.
多分支递归相当于是一颗树形结构
单分支递归相当于是一条道走到黑
eg:用递推公式求最大公约数
数学原理(问题划分为子问题的基础):辗转相除法
m%n=k k!=0
比如4和2, %2=0,所以2就是最大公约数
int func(int n,k)
{
(n%k==0? retrun k: return k%func(k,n%k));
}
这里代码写的不太好理解,大家可以手动模拟一下(#^ . ^#)
eg:递归形式写插入排序
1.划分:对数组的0~N-1进行排序
<->对数组的0~N-2进行排序,再将最后一个元素插入
就这样:问题缩小了一个规模
void insert_sort(int []arry,int k)
{
insert_sort(array,k-1); //重点1
int x=arry[k];
int index=k-1;
while(x<arry[index]){
arry[index+1]=arry[index];//index指向的元素后移
index--;
}
array[index+1]=x; //重点2
}
重点1:这里的insert_sort的位置很有讲究,我们在讲划分子问题时,假设的是K前面的数组都是有效的,所以这要求我们先进入到最后一个递归状态,直接return后开始依次将第二个元素插入到前面的位置中,当前递归结束后倒数第三层递归再对第三个元素进行插入,结束本层递归后,退回到第四层递归,再对第四个元素进行插入排序…依次进行
终点2:当插入的元素是7时,当前数组为
…6, 8,9…
此时的index指向的元素为8,后移后变为
…6,8,8…
此时index经过–操作后指向6,所以我们插入的位置就该是index+1,而不是index,这点要格外注意
eg:汉诺塔问题
问题描述:
https://blog.csdn.net/qq_37873310/article/details/80461767
问题的划分说简单也算简单,说难也有点难度
总体思想是将N-1个盘子通过目标柱的帮助移到辅助盘,将最后一个盘子移动到目标盘,再将这N-1个盘子通过原始盘的帮助移动到目标盘.就是这样简单粗暴O(∩_∩)O哈哈~
#include<iostream>
#include<cstdio>
using namespace std;
void Hanio(char A,char B,char C,int k) //假设初始时都在A,要移动到C
{
if(k==0) return ;
Hanio(A