递归之经典汉诺塔问题
前言
本博客仅做学习笔记,如有侵权,联系后即刻更改
科普:汉诺塔问题的起源
解题思路及实例解答
汉诺塔是一个递归问题,我们假设x层汉诺塔从A柱移到C柱(目标柱)的最快次数是f(x)次
以3个圆盘的移动做为示例,我们可以把整个过程分解为三个部分
一,把第一第二层移动到中间的柱子(过渡柱子),最快f(2)步
二,把第三层移动到最后一根柱子(目标柱子),最快1步
三,把刚才移动到中间柱子的第一第二层移动到最后一根柱子,最快f(2)步
所以f(3)=f(2)+1+f(2)=7
然后以此类推,这里算出了1-9个圆盘所需要移动最少次数
f(1)=1
f(2)=3
f(3)=f(2)+1+f(2)=7
f(4)=f(3)+1+f(3)=15
f(5)=f(4)+1+f(4)=31
f(6)=f(5)+1+f(5)=63
f(7)=f(6)+1+f(6)=127
f(8)=f(7)+1+f(7)=255
f(9)=f(8)+1+f(8)=511
f(x+1)=2*f(x)-1
再进一步,可以得到通项公式为
f(x)=2^x-1
汉诺塔x个圆盘移动最少次数为:
f(x)=2^x-1
Java实现
1.Java代码
代码如下:
import java.util.Scanner;
public class Hanoi {
// 全局变量记录移动次数
static int count;
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
while (scanner.hasNext()){
int n = scanner.nextInt();
// 计数变量初始化
count = 0;
hanoi(n,'A','B','C');
System.out.println("*******************");
System.out.println(n + "个圆盘最少需要移动" + count + "次。");
}
}
static public void hanoi(int n, char A,char B, char C){
// 当只剩下最后一个盘子时,直接从A柱移到C柱
if (n == 1)
move(n,A,C);
// 递归调用
// 先将n-1个盘子移动到B盘
// 再将最后一个盘子移动到C盘
// 最后将n-1个盘子移动到C盘
else {
hanoi(n-1,A,C,B);
move(n,A,C);
hanoi(n-1,B,A,C);
}
}
// 输出移动方法并且每次移动计数
static public void move(int plate, char start, char end){
count ++;
System.out.println(plate + "号盘从" + start + "号柱移动到" + end + "号柱");
}
}
2.代码运行示例:4个圆盘
总结
汉诺塔圆盘最少移动次数:f(x)=2^x-1
汉诺塔问题是经典的递归问题,一定要记得或者会推导最少递归次数的公式喔
就是这个:f(x)=2^x-1
小小励志
有些事你现在不做,一辈子都不会做了。
如果你想做一件事,全世界都会为你让路。
《搭车去柏林》