1. 程式人生 > >漢諾塔演算法問題的解法(Java)、思路以及舉一反三

漢諾塔演算法問題的解法(Java)、思路以及舉一反三

首先,先放程式碼,講解以及註釋將會在後文裡單獨寫出來

public class hnt {
	public static void main(String[] args) {
		hnts("a","b","c",3);
	}
	
	public static void hnts(String from,String temp,String to,int n){
		if(n==1){
			System.out.println(from+"------>"+to);
		}else{
			hnts(from,to,temp,n-1);
			hnts(from,temp,to,1);
			hnts(temp,from,to,n-1);
		}
		
	}
}

原始問題描述(來源百度百科)

相傳在古印度聖廟中,有一種被稱為漢諾塔(Hanoi)的遊戲。該遊戲是在一塊銅板裝置上,有三根柱子(編號A、B、C),在A杆至上而下、由大到小按順序放置64個金盤(如下圖)。遊戲的目標:把A杆上的金盤全部移動到C杆子上,並仍保持原有順序疊好。操作規則:每次只能移動一個盤子,並且在移動過程中三根杆上都始終保持大盤在下,小盤在上,操作過程中盤子可以置於A、B、C任一杆上。


解題思路

    首先,我們先統一一下環境設想,當一個漢諾塔擺在我們面前的時候,我們認定某塊圓盤是(任何柱)從上往下數第幾塊的時候,我們就給這塊圓盤設定一個編號為n

    然後給三個柱子設定一個以圓盤為視角的命名,分別是盤子目前所在的地方“from”,盤子想要到達的地方“to”,剩餘的另外一個可以作為臨時落腳點的柱子“temp”

    則概括漢諾塔規律一共分為四步:

            一:當這塊圓盤(n)是在最上層的時候,即n==1的時候,則這個盤子就可以直接從from移動到to     

            System.out.println(from+"------>"+to);
            二:當這塊圓盤(n)不是在最上層的時候,即它上邊還有圓盤的時候,我們需要把它上邊的那一塊圓盤(n-1)先移動到temp上
            hnts(from,to,temp,n-1);

            三:當圓盤(n)移動到temp之後,這時,圓盤n就會變成n-(n-1)=1,所以此時的圓盤n(現在是1)就可以直接移動到to

	    hnts(from,temp,to,1);
            四:當圓盤n(1),移動到to之後,我們就需要把放在temp上的(n-1)移動到to上
	    hnts(temp,from,to,n-1);

總結以及舉一反三

這四步其實是我們根據一定的經驗和嘗試總結的規律。

這道題的思考路線可以總結為一下部分,總結思考路線可以用以幫助我們以後面臨同樣的問題時,舉一反三:

        首先,當我們看到這道題時,我們可以先簡單帶入1,2個盤子進行嘗試,當我們嘗試有3個盤子的時候,我們就應該思考一下,這是一道可以用什麼方法解決的問題,經過1,2,3個盤子的嘗試,我們可以大致發現,這個移動是有一點規律的,好,那麼我們就基本可以猜到可以用迴圈或者遞迴試試了,但是顯然使用迴圈的話,對盤子的迴圈跳轉控制太弱,所以可以選擇使用遞迴,如果不行就再嘗試使用迴圈。

        既然選擇使用遞迴,那麼我們就開始思考,如何去找到這個規律。

        一般遞迴解決問題的概念大致可以理解為冰箱放大象:開啟冰箱門,把大象塞進去,關上冰箱門。  但是其中過程是怎麼塞進去的,怎麼關上門的,我們不用過多思考,我們只需要給它一個開始(傳參),和一個結束(出口)。所以此時我們就可以找到如上文所述的四個解決步驟。利用這四個步驟我們就可以找到問題的解決方案。