棧和佇列(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); } }