递归思想
递归的我设计经验
定义:如果一个方法或者函数调用了自己,那么这个叫做形式上的递归,但是该递归,为死循环,没有出口。
- 找重复
- 找重复中的变化量–>参数
- 找参数的变化趋势—>设计出口
public class Digui递归思想 {
public static int fun(int n){ //递归参数
if(n==1){ //递归出口
return 1;
}
return fun(n-1)+n; //递归循环的关键
}
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println(fun(5));
}
}
N的阶乘也是如此
public class Digui递归思想 {
public static int fun(int n){
if(n==1){
return 1;
}
return fun(n-1)*n; //就是换了个符号
}
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println(fun(6));
}
}
简单的数组求和
public static int fun(int[] arr,int len){
if(len==arr.length-1){ //出口
return arr[len];
}
return arr[len]+fun(arr,len+1);
}
public static void main(String[] args) {
// TODO Auto-generated method stub
int[] arr ={10,1,2,3,4,5,4};
System.out.println(fun(arr,0));
}
简单的字符翻转
public static String Strend(String str ,int lost){
if(lost==0){ //字符串最低位
return ""+str.charAt(lost);
}
return str.charAt(lost)+Strend(str,lost-1);
}
public static void main(String[] args) {
System.out.println(Strend("abcde",4));
}
总结
前面的递归为切蛋糕思想
数组求和为从前面开始切蛋糕(切数字)
翻转字符串为从后面切蛋糕(切数字)
而后面数学就没法使用切蛋糕思想
通过观察,
要先判断有没有递推公式?
有没有等价转换
斐波那契序列
1 1 2 3 5 8 13
多分支递归(递归时就像二叉树)
//斐波那契数列 1 1 2 3 5 8 13 21 ...
public static int fibo(int n){
if(n==1||n==2){
return 1;
}
return fibo(n-1)+fibo(n-2);
}
public static void main(String[] args) {
System.out.println(fibo(10));
}
将所有最底层,递归到1 或2 时都返回 1, 将所有返回的1加起来
斐波那契数列的递推公式f(n)=f(n-1)+f(n-2)
越到底层就越小,减到底层为 1或2返回1,然后返回上级加起来
最大公约数
首先理解何为最大公约数
public static int control(int m,int n){
if(n==0) return m;
return control(n,m%n);
}
public static void main(String[] args) {
System.out.println(control(6,15));
}
解析:当n>m时会自动调换位置
若未除尽有余数,当成参数传入下一个递归
若能除尽,下一个递归返回上一个递归传参数(n)即为当前递归的m
用递归来实现插入排序
static int[] arr={10,15,5,4,12,11};
public static void butt(){
for(int i=1;i<arr.length;i++){
int k=arr[i];
while(arr[i-1]>k){
int temp=arr[i];
arr[i]=arr[i-1];
arr[i-1]=temp;
if(i>1){
i--;
}
}
}
}
//分析首先该排序
//先取得一个数,与其他比自己前的数进行对比
//判断大小,进行交换
分析可以让递归代替外层循环,内层循环不用动
static int[] arr={10,15,5,4,12,11};
public static void paixu(int k){
if(k==0){return;};
paixu(k-1);
int x=arr[k];
int index=k-1;
while(index>-1&&x<arr[index]){
arr[index+1]=arr[index]; //直接将后索引数覆盖为前面索引数
index--;
}
arr[index+1]=x; //执行最后一项时多减一个1
}
public static void main(String[] args) {
paixu(arr.length-1);
for(int i=0;i<arr.length;i++){
System.out.println(arr[i]);
}}
汉诺塔问题
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner sc=new Scanner(System.in);
int n=sc.nextInt();
move(n,'A','B','C');
}
public static void move(int n,char frist,char soucd,char sed){
if(n==1){ //当某柱子只有一个盘时
System.out.println(frist+"->"+soucd);
}else{ //某柱子有多个盘子时
move(n-1,frist,sed,soucd); //先把N-1个盘子挪到辅助空间上去
System.out.println(frist+"->"+soucd);
move(n-1,soucd,frist,sed);
//让辅助柱的N-1个盘挪到原来空间去
}
}