演算法學習 類似漢諾塔的問題

2021-07-22 08:40:29 字數 2140 閱讀 9394

題目:

漢諾塔問題比較經典,這裡修改一下遊戲規則:

現在限制不能從最左側的塔直接移動到最右 側,也不能從最右側直接移動到最左側,而是必須經過中間。求當塔有 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個盤子,則先移...