算法很美(经典递归问题)

1.求斐波那契数
斐波那契数列为1 1 2 3 5 8 13 21…求第N项斐波那契数?

代码:

import java.util.*;
public class 斐波那契数列 {
public static void main(String[] args) {
	Scanner sc=new Scanner(System.in);
	int n=sc.nextInt();
	System.out.println("第"+n+"项斐波那契数是"+f(n));
	
}

private static int f(int n) {
	// TODO Auto-generated method stub
	if(n==1||n==2)
	{
		return 1;
	}
	return f(n-1)+f(n-2);
}
}

2.利用递归求两个数的最大公约数(辗转相除法)
辗转相除法流程图
在这里插入图片描述
第一次想出的代码

import java.util.*;
public class 利用递归模拟辗转相除法 {
//用辗转相除法求最大公约数
	public static void main(String[] args) {
		Scanner sc =new Scanner(System.in);
		int n=sc.nextInt();
		int m=sc.nextInt();
		System.out.println(f(n,m));
	}

private static int f(int n,int m) {
	// TODO Auto-generated method stub
	int a,b;
	if(n>=m)
	{
		 a=n;
		 b=m;
	}
	else {
		 a=m;
		 b=n;
	}
	int c=a%b;
	if(c==0)
	{
		return b;
	}
	else {
		return f(b,c);
	}
	
}
}

改进代码

import java.util.*;
public class 利用递归模拟辗转相除法 {
//用辗转相除法求最大公约数
	public static void main(String[] args) {
		Scanner sc =new Scanner(System.in);
		int n=sc.nextInt();
		int m=sc.nextInt();
		System.out.println(f(n,m));
	}

private static int f(int n,int m) {
	// TODO Auto-generated method stub
	int a,b;
	if(n>=m)
	{
		 a=n;
		 b=m;
	}
	else {
		 a=m;
		 b=n;
	}
	if(a%b==0)
		return b;
	return f(b,a%b);
	
}
}

3.用递归改进插入排序
思路:
1.找重复:先将前i-1个元素排好序,然后将第i个元素按顺序插入前面,不断 重复,直到到达数组第0个元素
2.找变化:变化的量是索引i
3.找出口:出口是索引到达第0个元素时结束
代码:

private static void f(int[] a, int i) {
	// TODO Auto-generated method stub
	if(i==0)
	{
		return;
	}
	f(a,i-1);
	int x=a[i];//将数组最后一个值赋给x
	int index=i-1;//标记数组倒数第二个数
	while(x<a[index]&&index>=-1)//卡index>=-1是因为数组中最少得有0个元素
	{
		//最后一个数比前一个小,所以前一个需要后移,给人家腾地方;而最后一个数x只是暂时在此轮放到index的位置
		a[index+1]=a[index];
		index--;//index往前推进
	}
	a[index+1]=x;
}
}

4.汉诺塔问题
在这里插入图片描述
1.找重复:把N个盘子从A移动到B
(1)先将上面N-1个盘子从A移动到C,此时A为源头,C为终点,B为辅助位
(2)再将最底层的盘子也就是第N个盘子,从A移动到B
(3)将N-1个盘子从C移动到B,此时C为源头,B为终点,A为辅助位
2.找变化:不断变化的是所利用的盘子的数量N
3.找出口:当只剩一个盘子时,直接将它从A移动到B
代码:

import java.util.*;
public class 汉诺塔问题 {
public static void main(String[] args) {
	Scanner sc =new Scanner(System.in);
	System.out.print("初始化汉诺塔层数为");
	int N=sc.nextInt();
	System.out.println("步骤为");
	f(N,"A","B","C");
}

private static void f(int n,String from,String to,String help) {
	// TODO Auto-generated method stub
	if(n==1)
	{
		System.out.println("移动第"+n+"个盘子从"+from+"到"+to);
	}
	else
	{
	f(n-1,from,help,to);
	System.out.println("移动第"+n+"个盘子从"+from+"到"+to);
	f(n-1,help,to,from);
	}
}
}

效果:
在这里插入图片描述
5.递归形式的二分查找
二分查找的前提是:数组已经排好序(顺序排列)

import java.util.*;
public class 递归思想的二分查找 {
public static void main(String[] args) {
	Scanner sc =new Scanner(System.in);
	int []a= {3,6,9,12,20};
	System.out.print("请输入要查找的数");
	int key=sc.nextInt();
	System.out.println("该数在序列中的索引为"+f(a,0,a.length-1,key));
	
}

private static int f(int []a,int low,int high,int key) {
	// TODO Auto-generated method stub
	if(low>high)
	{
		return -1;
	}
	int mid=low+((high-low)>>1);//移位操作算出一组序列的中间索引
	int x=a[mid];
	if(key==x)
	{
		return mid;
	}
	else if(key<x)//查找值小于中间值
	{
		return f(a,0,mid-1,key);
	}
	else {//查找值大于中间值
		return f(a,mid+1,high,key);
	}
}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值