目录
汉诺塔:
问题描述:
代码:
运行原理分析:
运行结果:
内存分析图:
计算步数:
思路:
关键点:
代码:
从左至右依次有A,B,C三个塔,A塔上有若干个由上到下,由小到大排列的圆盘,要求将圆盘从A塔移动到C塔,必须保证大圆盘在下,小圆盘在上的排列规则
假如共有5层
第一步:需要把1~4层从A->B,然后把第5层从A->C
第二步:需要把1~3层从B->A,然后把第4层从B->C
第三步:需要把1~2层从A->B,然后把第3层从A->C
第四步:需要把第1层从B->A,然后把第2层从B->C
第五步:需要把第1层从A->C
//汉诺塔问题
public class HanoiTower{
//编写一个main方法
public static void main(String[] args){
Tower t1 = new Tower();
t1.move(2, 'A', 'B', 'C');
}
}
class Tower{
//一共有A,B,C三个塔,A塔上有n个圆盘,从上到下由小到大的顺序垒在一起的,
//请将A塔上的圆盘移动到C塔,移动过程中必须是小圆盘在大圆盘上面
//返回数据类型:void
//方法名:move移动
//形参:(int num, char a, char b, char c)
//num表示要移动的圆盘的个数,a,b,c表示A塔,B塔,C塔
public void move(int num, char a, char b, char c){
//分为两种情况:1)只有一个圆盘2)多个圆盘
if(num == 1){//只有一个圆盘,直接从a到c
System.out.println(a + "->" + c);
}else{//有多个圆盘
//1)将最后一个圆盘外的其余圆盘全都从a移动到b,需要借助c
move(num-1, a, c, b);
//2)将有一个圆盘,直接从a移动到c
System.out.println(a + "->" + c);
//将其余圆盘通过a从b移动到c
move(num-1, b, a, c);
}
}
}
两层:先把上面的一层从A塔移动到B塔,然后把底层的从A塔移动到C塔,再把B塔的圆盘移动到C塔;即A->B;A->C;B->C;
理解代码的关键点:即使方法内形参的位置发生了变化,调用方法时的传递的实参的位置是不变的;即move(int num, char a, char b, char c);对应的实参move(2, 'A', 'B', 'C'); 方法move(num-1, a, c, b);对应的实参是move(1, 'A', 'B', 'C');
计算完成一个汉诺塔的移动需要多少步?
1)添加一个变量count(必须在方法之外定义,否则会导致每次调用方法时count会再次归零)
2)在递归结束时返回
3)在mian方法内接收返回的count然后输出
count++添加的地方;
//汉诺塔问题
public class HanoiTower02{
//编写一个main方法
public static void main(String[] args){
int count = 0;
Tower t1 = new Tower();
count = t1.move(6, 'A', 'B', 'C');
System.out.println("从A塔到C塔一共移动了" + count + "次");
}
}
class Tower{
//一共有A,B,C三个塔,A塔上有n个圆盘,从上到下由小到大的顺序垒在一起的,
//请将A塔上的圆盘移动到C塔,移动过程中必须是小圆盘在大圆盘上面
//返回数据类型:void
//方法名:move移动
//形参:(int num, char a, char b, char c)
//num表示要移动的圆盘的个数,a,b,c表示A塔,B塔,C塔
int count = 0;
public int move(int num, char a, char b, char c){
//分为两种情况:1)只有一个圆盘2)多个圆盘
if(num == 1){//只有一个圆盘,直接从a到c
System.out.println(a + "->" + c);
count ++;//计算移动次数
}else{//有多个圆盘
//1)将最后一个圆盘外的其余圆盘全都从a移动到b,需要借助c
move(num-1, a, c, b);
//2)将有一个圆盘,直接从a移动到c
System.out.println(a + "->" + c);
count ++;//计算移动次数
//将其余圆盘通过a从b移动到c
move(num-1, b, a, c);
}
return count;
}
}