1. 程式人生 > >棧和佇列(6)--用棧來求解漢諾塔問題①

棧和佇列(6)--用棧來求解漢諾塔問題①

要求:

        約束不能從最左側的塔直接移動到最右側,也不能從最右側直接移到最右側,必須經過中間。求當塔為N層的時候,列印最優移動過程和最優移動總步數。

思考:

     用遞迴的方法--

如果只剩下最上層的塔需要移動,

1.如果希望從“左”移到“中”,列印“Move 1 from left to mid”。

2.如果希望從“中”移到“左”,列印“Move 1 from mid to left”。

3.如果希望從“中”移到“右”,列印“Move 1 from mid to right”。

4.如果希望從“右”移到“中”,列印“Move 1 from right to mid”。

5.如果希望從“左”移到“右”,列印“Move 1 from left to mid”和“Move 1 from mid to right”。

6.如果希望從“右”移到“左”,列印“Move 1 from right to mid”和“Move 1 from mid to left”。

多層情況,如果剩下N層,從最上到最小依次為1~N,則:

1.如果剩下的N層都在“左”,希望全部移到“中”,則有三個步驟。

①將1~N-1層塔先全部從“左”移到“右”,利用遞迴;

②將第N層塔從“左”移到“中”;

③再將1~N-1層塔全部從“右”移動到“中”,利用遞迴。

2.如果剩下的N層塔從“中”移到“左”,從“中”移到“右”,從“右”移到“中”,過程與情況1同理。

3.如果剩下的N層塔都在“左”,希望全部移到“右”,有五個步驟。

①將1~N-1層塔先全部從“左”移到“右”,利用遞迴;

②將第N層塔從“左移到”中”;

③將1~N-1層塔全部從“右”移到”左”,利用遞迴;

④將第N層塔從“中”移到“右”;

⑤最後將1~N-1層塔全部從“左”移動“右”,利用遞迴。

4.如果剩下的N層塔都在“右”,希望全部放到“左”,過程和3一樣

程式碼實現:

package algorithm_6;

public class algorithm_6 {
public static int hanoiProblem1(int num ,String left, String mid, String right){
	if(num < 1 ){
		return 0 ;
	}
	return process(num, left, mid, right, left, right);
}
public static int process(int num, String left, String mid, String right, String from, String to){
	if(num == 1 ){
		if(from.equals(mid) || to.equals(mid)){
			System.out.println("Move 1 from " + from + " to " + to);
			return 1;
		}
		else{
			System.out.println("Move 1 from " + from + " to " + mid);
			System.out.println("Move 1 from " + mid + " to " + to);
			return 2;
		}
	}
	if(from.equals(mid) || to.equals(mid)){
		String another = (from.equals(left) || to.equals(left)) ? right :left;
		int part1 = process(num - 1, left, mid, right, from, another);
		int part2 = 1;
		System.out.println("Move " + num + " from " + from + " to " + to);
		int part3 = process(num - 1, left, mid, right, another, to);
		return part1 + part2 + part3;
	}else{
		int part1 = process(num - 1, left, mid, right, from, to);
		int part2 = 1;
		System.out.println("Move " + num + " from " + from + " to " + mid);
		int part3 = process(num - 1, left, mid, right, to, from);
		int part4 = 1;
		System.out.println("Move " + num + " from " + mid + " to " + to);
		int part5 = process(num - 1, left, mid, right, from, to);
		return part1 + part2 + part3 + part4 + part5;
	}
}
public static void main(String[] args) {
	String str1 = "left";
	String str2 = "mid";
	String str3 = "right";
	hanoiProblem1(3, str1, str2, str3);
}

}