漢諾塔問題遞迴與非遞迴演算法

2022-08-31 09:06:07 字數 1397 閱讀 4755

漢諾塔問題描述如下:

有 a、b、c 3 根針,n 個圓盤(從 1..n )從上到下,按小到大順序放在 a 處,要求每次移動乙個,並保持從小到大的疊放順序,

利用 c,把 n 個盤子移動到 b 處。

遞迴演算法比較容易理解

fn hanoi(n):

hanoi_move(n, 'a', 'b', 'c')

fn hanoi_move(n, from, to, medium):

if n <= 0:

return

hanoi_move(n-1, 'a', 'c', 'b')

println("move {} from {} to {}", n, from, to);

hanoi_move(n-1, 'c', 'b', 'a')

重新思考整個移動過程,在處理 n 從 a 到 b 時,需要先處理其上的 n-1 個圓盤從 a 到 c,直到 a 處只剩下 1 個編號為 n 的圓盤,這個步驟定義為 step :

struct step
r 表示當前編號為 n 其上面還放著有多少個圓盤,當r為 1 時,就可以移動編號為 n 的圓盤了,即:

step(n, r, from, to, medium) 分解為

1. step(r-1, r-1, from, medium, to)

2. step(n, 1, from, to, medium)

3. step(r-1, r-1, medium, to, from)

可利用棧或雙向佇列儲存中間狀態,一直到分解完成,注意,用棧儲存時方向與分解方向相反:

fn hanoi_move_stack(n, from, to, medium):

if n <=0:

return

s = stack()

s.push(step(n, n, from, to, medium)):

while !s.is_empty():

step = s.pop()

if step.r == 1:

println("move {} from {} to {}", step.n, step.from, step.to)

else:

s.push(step(step.r-1, step.r-1, step.medium, step.to, step.from))

s.push(step(step.n, 1, step.from, step.to, step.medium))

s.push(step(step.r-1, step.r-1, step.from, step.medium, step.to))

漢諾塔非遞迴演算法

輸入格式 輸入為乙個正整數n,即起始柱上的盤數。輸出格式 每個操作 移動 佔一行,按柱1 柱2的格式輸出 輸入樣例 3輸出樣例 a c a b c b a c b a b c 乙個美國學者總結得到 所有的漢諾塔移動可以總結為重複的兩步,我們假設現在最小的圓盤在a柱子上,柱子為a,b,c 第二步 對a...

非遞迴 遞迴 漢諾塔演算法實踐

漢諾塔演算法是很多公司的面試題,經常會讓手寫,這裡總結了一下 1 最最最常見的也是最簡單的漢諾塔演算法,遞迴 這也是學習遞迴的乙個經典演算法題 漢諾塔演算法 遞迴 ps 列印移動過程 param level 層數 param from 起始位置 param to 目標位置 param other 多...

漢諾塔問題非遞迴演算法集錦

漢諾塔問題非遞迴演算法集錦 漢諾塔問題介紹 在印度,有這麼乙個古老的傳說 在世界中心貝拿勒斯 在印度北部 的聖廟裡,一塊黃銅板上插著三根寶石針。印度教的主神梵天在創造世界的時候,在其中一根針上從下到上地穿好了由大到小的64片金片,這就是所謂的漢諾塔。不論白天黑夜,總有乙個僧侶在按照下面的法則移動這些...