汉诺塔
实验内容
-
设a, b, c是3个塔座:开始时,塔座a上有n个自上而下、由小到大地叠在一起圆盘,各圆盘从小到大编号为1, 2, …, n,现要求将塔座a上的这一叠圆盘移到塔座b上,并仍按同样顺序叠置,移动圆盘时遵守以下移动规则:
-
规则1:每次只能移动1个圆盘;
-
规则2:不允许将较大的圆盘压在较小的圆盘之上;
-
规则3:在满足移动规则1和2的前提下,可将圆盘移至a, b, c中任一塔座上。
(1) 算法设计思路假设a为初始塔座,b为临时放置点,c为目标塔座。可将圆盘1、2、3看作是一个整体,记为A,圆盘4记为B。所以可以
1.先将A移动到塔座b。
2.将B移动至塔座c。
3.将A移动至塔座c。
整个操作过程就完成了。
细分:
- 当只有一个圆盘时,直接将圆盘移动到目标塔座。(作为基值条件)
- 当不止一个圆盘时,要把上面的n-1个盘子,借助塔座c,将n-1个圆盘移动至临时塔座b。
- 最后只剩下一个最大的圆盘时,就将此圆盘移动到目标塔座c。
- 此时,塔座b有n-1个圆盘,再借助塔座a,将n-1个圆盘移动至目标塔座c。
(2).算法实现功能
算法:hanoi(a, b, c,n)
输入:圆盘数目:int n
输出:圆盘移动到目标塔座的步骤
S1: if n==1 then
S2: move(a,c)
S3: return
S4: end if
S5: hanoi(a,c,b,n-1)
S6: move(a,c)
S7: hanoi(b,a,c,n-1)
(3)实现代码
import java.util.Scanner;
public class MyHanoi {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
char a = 'a';
char b = 'b';
char c = 'c';
int n = in.nextInt();
hanoi(a,b,c,n);
}
private static void hanoi(char a, char b, char c, int n) {
//当n = 1时,即塔座只有一个圆盘,直接将此圆盘移动到目标塔座。
if(n == 1){
System.out.println("圆盘"+n+" "+a+"---->"+c);
return;
}
//当塔座的圆盘数量>1时,需要借助塔座c,将上面的n-1个圆盘移动到塔座b
hanoi(a,c,b,n-1);
//只剩下一个最大的圆盘,故将最底下的圆盘移动到目标塔座
System.out.println("圆盘"+n+" "+a+"---->"+c);
//将n-1个圆盘借助塔座a,移动到目标塔座c
hanoi(b,a,c,n-1);
}
}
(4)时间复杂度分析
将(n-1)个圆盘借助a移动到b需要T(n-1)步,将最大的圆盘移动到c需要1步,再将(n-1)个圆盘从b移动到c需要T(n-1)步。故递推公式:
式子两边相加,可得