題目:
漢諾塔問題比較經典,這裡修改一下遊戲規則:
現在限制不能從最左側的塔直接移動到最右 側,也不能從最右側直接移動到最左側,而是必須經過中間。求當塔有 n 層的時候,列印
最優移動過程和最優移動總步數。
例如,當塔數為兩層時,最上層的塔記為 1,最下層的塔記為 2,則列印:
move 1 from left to mid
move 1 from mid to right
move 2 from left to mid
move 1 from right to mid
move 1 from mid to left
move 2 from mid to right
move 1 from left to mid
move 1 from mid to right
it will move 8 steps.
【要求】
用以下兩種方法解決。
方法一:遞迴的方法;
方法二:非遞迴的方法,用棧來模擬漢諾塔的三個塔。
這個問題和經典的漢諾塔很像咯,漢諾塔是最經典的聯絡遞迴的演算法了,這裡左神用遞迴和非遞迴(棧)兩種方式來實現了;
遞迴
// 遞迴做
public static int hanoiproblem1(int n,string left,string mid,string right)
// from —> to
public static int process1(int n,string left,string mid,string right,string from,string to)else
}// 其他情況(即 多層塔層疊)
// 存在mid移動的情況,分三步
if(from.equals(mid) || to.equals(mid))else
}
上面就是遞迴操作的演算法了,主要是分情況進行分析,這裡要注意,很多人會問規則不是 只能從 mid 經過才能走嗎,為什麼還有類似於
int part1=process1(n-1,left,mid,right,from,another);
這樣(可能直接 left->right的**呢),請注意,這是遞迴操作,我們只需要注意print的操作是完全符合 遊戲規則就可以了,遞迴操作進入再分析的時候就會符合遊戲規則啦~~
非遞迴操作(棧操作)
對於棧操作的時候,需要有幾點說明:
首先,對於移動漢諾塔,符合要求的操作只有4種,ltom,mtol,mtor,rtom;
其次,由於要求的是最少步數,也就是如果前一步是ltom,則這步絕對不可能是mtol(這樣不就迴圈操作了嗎,怎麼可能是最優步數);
最後,操作的規則,只能小壓大;
對了,還有乙個小的trick,為了使得初始化時都可以壓入資料,事先在棧中壓入最大值(不壓入的話,需要處理當棧為空的情況);
鑑於上述規則,我們可以定義3個棧來進行操作,**如下:
public static enum action
// 棧做
public static int hanoiproblem2(int n,string left,string mid,string right)
// record主要是記錄上一次的操作
action record=;
int step=0;
while(tstack.size()!=n+1)
return step;
}public static int process2(action record,action prenoact,action curact,stackfstack,
stacktstack,string from,string to)
// 本次操作允許,記錄
tstack.push(fstack.pop());
system.out.println("move "+tstack.peek()+" from "+from+" to "+to);
record[0]=curact;
return 1;
}
以上就是這個問題的求解過程了,比較能練手,好評~~~ 演算法學習 遞迴之漢諾塔
漢諾塔問題 如下圖所示,從左到右有a b c三根柱子,其中a柱子上面有從小疊到大的n個圓盤,現要求將a柱子上的圓盤移到c柱子上去,期間只有乙個原則 一次只能移到乙個盤子且 子不能在小盤子上面,求移動的步驟和移動的次數 1個盤的時候,只需要移動1次即可達成目標,g 1 1 步驟一 2個盤的時候,需要移...
漢諾塔演算法
最簡步驟 2的n次冪 1 為了實現 n個盤從 借助c 從a 移動到 b 思路如下 首先考慮極限當只有乙個盤的時候 只要 盤直接從 a b即可 那麼當有2個盤的時候就只要先把1號盤從a c 然後 把2號盤 a b 再 把 2好盤從 c b 那麼當有n個盤的時候你只要先把 n 1個 盤 借助 b 移動到...
漢諾塔演算法
解法 如果柱子標為abc,要由a搬至c,在只有乙個盤子時,就將它直接搬至c,當有兩個盤子,就將b當作輔助柱。如果 盤數超過兩個,將第三個以下的盤子遮起來,就很簡單了,每次處理兩個盤子,也就是 a b,a c,b c這三個 步驟,而被遮住的部分,其實就是進入程式的遞迴處理。事實上,若有n個盤子,則先移...