Java基础语法(汉罗塔)
1 起源
汉罗塔(又称河内塔)问题是源于印度一个古老传说的益智玩具。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。
2 需求
将汉罗塔问题抽象到数学:
- 1.有三根杆子 A,B,C;
- 2.A 杆上有若干大小不同的碟子,从上往下越来越大;
- 3.每次移动一块碟子,小的只能叠在大的上面;
- 4.把所有碟子从 A 杆全部移到 C 杆上。
3 分析
- 确定 A 柱子上的初始碟子:int disks = 3;
- 确定三个容器 char ‘A’、char ‘B’、char ‘C’;
- 初始确定移动方法,从 from --> to:hanrotaMove(int disks, char from, char index, char to)。
3.1 1个碟子
A 柱子上只有一个碟子时,直接移动到 C:
num | from | index | to | mv |
---|---|---|---|---|
1 | A | B | C | A–>C |
3.2 2个碟子
num | from | index | to | mv |
---|---|---|---|---|
1 | A | C | B | A–>B |
2 | A | B | C | A–>C |
1 | B | A | C | B–>C |
3.3 3个碟子
num | from | index | to | mv |
---|---|---|---|---|
1 | A | B | C | A–>C |
2 | A | C | B | A–>B |
1 | C | A | B | C–>B |
3 | A | B | C | A–>C |
1 | B | C | A | B–>A |
2 | B | A | C | B–>C |
1 | A | B | C | A–>C |
3.4 4个碟子
num | from | index | to | mv |
---|---|---|---|---|
1 | A | C | B | A–>B |
2 | A | B | C | A–>C |
1 | B | A | C | B–>C |
3 | A | C | B | A–>B |
1 | C | B | A | C–>A |
2 | C | A | B | C–>B |
1 | A | C | B | A–>B |
4 | A | B | C | A–>C |
1 | B | A | C | B–>C |
2 | B | C | A | B–>A |
1 | C | B | A | C–>A |
3 | B | A | C | B–>C |
1 | A | C | B | A–>B |
2 | A | B | C | A–>C |
1 | B | A | C | B–>C |
3.5 规律
在上述前 4个下不难发现有规律存在:
A 柱子上有 n 个碟子,移动步骤便以 n 分为上下两部分,且上部分移动的数与下部分移动的数相同,此处便有递归分治的思想,解析 4 个碟子:
在初始入参:from ‘A’ - index ‘B’ - to ‘C’ 下,每一级都做为下一级分支的入参,且每个分支的上部都有相同的步骤“换”:from-to-index,每个分支的下部也都有相同的步骤“换”:index-from-to,可将此图看为完全二叉树。
4 代码实现:直接算法
代码常规实现:Hanrota.java
/**
* @author zc
* @date 2021/10/29 9:30
* 汉罗塔
* 1.有三根杆子 A,B,C;
* 2.A 杆上有若干大小不同的碟子,从上往下越来越大;
* 2.每次移动一块碟子,小的只能叠在大的上面;
* 3.把所有碟子从 A 杆全部移到 C 杆上。
*
* main(String[] args):主方法,主程序入口;
* hanrotaMove(int disks, char from, char index, char to):方法,汉罗塔移动
*/
public class Hanrota {
/**
* 主程序入口
* @param args 系统参数
*/
public static void main(String[] args) {
// 初始化一个 A 柱子上碟子数
int disks = 4;
hanrotaMove(disks, 'A', 'B', 'C');
}
/**
* 汉罗塔移动
* @param disks 待移动碟子数量
* @param from 起始点
* @param index 过渡点
* @param to 目标点
*/