1. 程式人生 > >【java資料結構】遞推解決的漢諾塔問題

【java資料結構】遞推解決的漢諾塔問題

在學習資料結構的時候,遇到漢諾塔問題,就寫了自己的理解,希望對您有幫助。

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

}