文章目录
本文篇幅较长,建议仔细耐心看完,相信会有极大的收获。
一、最具启发性的汉诺塔问题
1、汉诺塔问题描述
有三根杆子A,B,C。A杆上有 N 个 (N>1) 穿孔圆盘,盘的尺寸由下到上依次变小。要求按下列规则将所有圆盘移至 C 杆:每次只能移动一个圆盘;大盘不能叠在小盘上面。
问:最少要移动多少次?并打印每次移动的情况。
2、从最初开始
我们的目标是将1、2、3圆盘从左杆移到右杆上
可以拆解为以下三步
1)(大步)将1、2圆盘从左移到中杆上
2)将3圆盘从左移到右杆上
3)(大步)将1、2圆盘从中移到右杆上
代码如下:
/**
* @author Java和算法学习:周一
*/
public static void leftToRight(int n) {
if (n == 1) {
// base case
System.out.println("Move 1 from left to right");
return;
}
// 1、1到n-1个圆盘从左到中
leftToMid(n - 1);
// 2、从左到右
System.out.println("Move " + n + " from left to right");
// 3、1到n-1个圆盘从中到右
midToRight(n - 1);
}
整个左到右方法,你会发现第一大步依赖左到中子方法,第三大步依赖中到右子方法,然后你去补起左到中方法、中到右方法;此时又会发现左到中依赖左到右、右到中方法,中到右依赖中到左、左到右方法……
/**
* @author Java和算法学习:周一
*/
private static void leftToMid(int n) {
if (n == 1) {
System.out.println("Move 1 from left to mid");
return;
}
leftToRight(n - 1);
System.out.println("Move " + n + " from left to mid");
rightToMid(n - 1);
}
private static void midToRight(int n) {
if (n == 1) {
System.out.println("Move 1 from mid to right");
return;
}
midToLeft(n - 1);
System.out.println("Move " + n + " from mid to right");
leftToRight(n - 1);
}
private static void rightToMid(int n) {
if (n == 1) {
System.out.println("Move 1 from right to mid");
return;
}
rightToLeft(n - 1);
System.out.println("Move " + n + " from right to mid");
leftToMid(n - 1);
}
private static