- 何为递归算法
所谓递归,通俗易懂的理解就是方法自己直接或者间接的调用自己来实现一些复杂的操作;
自己调用自己?那不一直调用变成死循环了嘛?别急,如果我们提前定义好了出口,等调用到出口那里就终止调用,这样就可以完美解决死循环的问题了。
下面通过递归算法求阶乘与汉诺塔两个小例子来熟悉下递归的思想。
1.计算阶乘
当求第n个数的阶乘的时候,我们只需要知道n-1的阶乘即可,通过n*(n-1)的阶乘就可以求出n的阶乘;
public static void main(String[] args) {
Scanner scanner=new Scanner(System.in);
System.out.print("请输入阶乘数:");
int i = scanner.nextInt();
int result=getJieCheng(i);
System.out.println(i+"的阶乘结果为:"+result);
}
/**
* 利用递归实现n的阶乘
* 1的阶乘 =1
* 2的阶乘 =2*1=2
* 3的阶乘 =3*2*1=6
* 4的阶乘 =4*3*2*1=24
*/
private static int getJieCheng(int i) {
//定义出口 如果为1则我们就返回数据,否则继续递归调用下去
if(i==1){
return 1;
}else{
return i*getJieCheng(i-1);
}
}
结果如下图所示:
2.斐波那契数列
什么是斐波那契数列?
数列中的第一个与第二数为1,其他每个元素等于前两个元素之和,例如8个数的斐波那契数列为:1,1,2,3,5,8,13,21;这种数列可以通过递归的方式求解出第n个数的值为多少
/**
* 斐波那契
*/
public static void main(String[] args) {
int i=printNum(8);
System.out.println("递归实现斐波那契"+i);
}
/**
* 使用递归规则实现斐波那契数列
* 1 1 2 3 5 8 13 21 .....
*/
private static int printNum(int n) {
//定义出口
if(n==1 || n==2){
return 1;
}else{
return printNum(n - 1) + printNum(n - 2);
}
}
如下图所示:通过递归方式实现,数列中第8个数的值为21
3.汉诺塔
什么是汉诺塔?
如上图所示,有三个柱子,第一个从小到大摞着3片黄金圆盘。现在把圆盘按大小顺序重新摆放在最后一个柱子上。并且规定,在小圆盘上不能放大圆盘,在三个柱子之间一次只能移动一个圆盘。也就是说将 from 上的圆盘全部移动到 to 上,并且要保证小圆盘始终在大圆盘上。那如何来求解呢?很明显这道题大家都知道使用递归的方式来做。
我们给三个柱子分别定义为A柱子,B柱子,C柱子
如果只有一个盘子:
那直接将圆盘从A柱子移动到C柱子上(出口)
如果有n个盘子
1.首先将n-1个盘子从A柱子借助C柱子移动到B柱子上
2.再将A柱子上第n个盘子从A柱子上移动到C柱子上
3.接下来我们将B柱子上剩余的n-1个盘子看做一个整体,将他们借助A柱子移动到C柱子上,这样就解决问题了
上代码:
public static void main(String[] args) {
String A="A柱子",B="B柱子",C="C柱子";//代表三个柱子
Scanner sc=new Scanner(System.in);
System.out.print("请输入盘子数目:");
int n=sc.nextInt();
move(n,A,B,C);
}
/**
* 如果只有一个盘子,
* 直接将A柱子上的盘子直接放到C柱子上
* 否则
* 1.将A柱子上的n-1个盘子借助与C放到B柱子上
* 2.然后将第n个盘子从A柱子放到C柱子上
* 3.将B柱子上的n-1个盘子借助A移到C柱子上
*/
public static void move(int n,String A,String B,String C){
//出口
if(n==1){
System.out.println("将第"+n+"个盘子从"+A+"移动到"+C);
}else{
move(n-1,A,C,B);
System.out.println("将第"+n+"个盘子从"+A+"移动到"+C);
move(n-1,B,A,C);
}
}
运行结果如下图所示:
记一次递归整理