漢諾塔演算法問題的解法(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個盤子的嘗試,我們可以大致發現,這個移動是有一點規律的,好,那麼我們就基本可以猜到可以用迴圈或者遞迴試試了,但是顯然使用迴圈的話,對盤子的迴圈跳轉控制太弱,所以可以選擇使用遞迴,如果不行就再嘗試使用迴圈。
既然選擇使用遞迴,那麼我們就開始思考,如何去找到這個規律。
一般遞迴解決問題的概念大致可以理解為冰箱放大象:開啟冰箱門,把大象塞進去,關上冰箱門。 但是其中過程是怎麼塞進去的,怎麼關上門的,我們不用過多思考,我們只需要給它一個開始(傳參),和一個結束(出口)。所以此時我們就可以找到如上文所述的四個解決步驟。利用這四個步驟我們就可以找到問題的解決方案。