【java資料結構】遞推解決的漢諾塔問題
阿新 • • 發佈:2018-12-11
在學習資料結構的時候,遇到漢諾塔問題,就寫了自己的理解,希望對您有幫助。
package com.qxlx.six; /** * 遞推解決的漢諾塔問題 * * @author jia * */ public class TowerApp { public static void main(String[] args) { doTowers(3, 'A', 'B', 'C'); } /** * 理解:漢諾塔問題 如果試圖要移動的盤子是奇數個盤子,開始時直接把最頂端的盤子移動到想要把這顆樹移動到的那個數上 * 如果檢視要移動的盤子是偶數個盤子,開始時直接把最頂端的盤子移動到中介塔座上。 如何理解這個問題, 假設把問題具體化,典例話, * 現在假象這樣一種情況,如果在A處只有一個盤子的話,想要將這一個盤子直接移動到C處,那麼就可以直接 * 移動到C處了。這是奇數的情況下,但是如果是偶數,或者是0個盤子的話,那麼就需要先將A處最上面的那個盤子 * 先移動到B處,將A處最後一個盤子移動到C處。然後將B處的盤子移動到C處,這樣的話,就可以實現了目的。 * * * xiaogong 理解:假設初始盤子數目為奇數,那麼最上面的盤子一定先從A到C,即遞迴到最後一層時,topN == 1, * 所以from、inner、to的值分別為‘A’‘B’‘C’。那麼此層遞迴完畢,返回上層遞迴。由於此層遞迴是 * 最上面的盤子從A到C,那麼上一層遞迴也就是下一步操作一定第二個盤子是A到B,【那麼上一層的from、 * inner、to一定是‘A’‘C’‘B’!!!】。將第二個盤子移到B了以後,第三步操作毋庸置疑是將先前 * 移到C的第一個盤子移到B,應該再遞迴一次,並且.已經知道了from、inner、to的值。此時,我們已經分 * 析完了最裡面兩層的操作。第三層的引數又是什麼呢?其實這時候又迴歸了第一層,即from、inner、to * 的值分別為‘A’‘B’‘C’。這一步操作是將第三個盤子從A移到C。這一層還有一個遞迴操作是將B上面 * 的兩個盤子移到C即第三個盤子上面。至此,3個盤子已經完美地從A移到了C。如果還有第四個、第五個盤 子,以此類推。 * * @param tonN * 頂部的盤子 * @param from * 源塔座(頂部盤子的起點) A * @param inner * 中介塔座(中介作用) B * @param to * 目標塔座(頂部盤子的終點) C */ public static void doTowers(int tonN, char from, char inner, char to) { // 如果只有一塊盤子,直接移動過去就可以了 if (tonN == 1) System.out.println("Disk 1 from " + from + " to " + to); // A C else { // 否則的話 就先把 n-1塊移動到中間 doTowers(tonN - 1, from, to, inner);// from > inner A B // 然後把最後 System.out.println("Disk " + tonN + " from " + from + " to " + to); // 把中間的一塊移動到to doTowers(tonN - 1, inner, from, to);// } } public static void doTorwers2(int number, char from, char center, char to) { // 假如是一塊盤子的話,直接從A移動到C處 if (number == 1) System.out.println("Disk 1 " + from + " to" + to);// A --->C else { doTorwers2(number - 1, from, to, center);// A--->B System.out.println("Disk " + number + "from " + from + "to" + to); doTorwers2(number - 1, center, from, to);//B--->C } } public static void doTowers3(int number,char from,char center,char to){ if(number==1) System.out.println("Disk 1 "+from+" to "+to); //A-C else{ doTowers3(number-1, from, to,center );//A-B System.out.println("Disk "+from+" to "+center); doTowers3(number-1, center, from, to);//B-C } } }