Java学习之汉诺塔问题

目录

汉诺塔:

问题描述:

代码:

运行原理分析:

运行结果:

内存分析图:

计算步数:

思路:

关键点:

代码:


汉诺塔:

问题描述:

从左至右依次有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;

运行结果:

Java学习之汉诺塔问题_第1张图片

内存分析图:

理解代码的关键点:即使方法内形参的位置发生了变化,调用方法时的传递的实参的位置是不变的;即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'); 

Java学习之汉诺塔问题_第2张图片

计算步数:

计算完成一个汉诺塔的移动需要多少步?

思路:

        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;
		
	}
}

你可能感兴趣的:(学习)