漢諾塔問題的遞迴和非遞迴實現

2021-08-18 13:02:42 字數 1314 閱讀 4858

漢諾塔問題:古代有乙個梵塔,塔內有3個基座,a基座上有64個盤子,盤子大小不等,大的在下,小的在上。有乙個老和尚想把盤子由a座移到b座,但每次只能移動乙個盤子,3個基座上的盤子都始終保持大的在下,小的在上。移動過程中可以利用c基座做輔助,求解其移動過程。

漢諾塔問題是遞迴演算法比較經典的例題,幾乎是每個老師講解遞迴演算法時都會講到的問題,對於任意n階漢諾塔問題,假設有3個基座a,b, c。在基座a上放置有n個直徑大小各不同,從小到大依次編號為:1、2、3…n。移動時遵循以下規則:

1)每次只能移動乙個盤子。

2)盤子可以放置在a、b、c、中的任何乙個基座上。

3)任何時候都不能將乙個較大的盤子放在較小的盤子上。

如何實現將a上的盤子按規則移動到b盤上呢?根據遞迴演算法的思想:將乙個大型複雜的問題層層轉化為乙個與原問題相似的規模較小的問題,在逐步求解小問題後,再回溯得到大問題的解。我們將問題進一步分解,當只有乙個盤子是,我們只需要將a基座上的盤子直接移動到b基座上即可,當有兩個盤子是,我們可以借助c基座完成移動過程。具體移動步驟為:a->c(第1個盤子),a->b(第2個盤子),c->b(第1個盤子);把n個盤子抽象的看作「兩個盤子」,「乙個」由1~n-1號組成,最底下是n號盤子,則移動過程為:

把n階漢諾塔問題記作hanoi(int n, char a, char b, char c),這裡的a,b,c並不總代表a、b、c三個底座,其意義為:第乙個引數n代表基座上的盤子數,a:代表每一次移動的起始基座,b:代表每一次移動的終點基座,c:代表每一次移動的輔助基座。由上述約定,以後的操作等價於:

具體移動過程如下圖:

理解了上面的過程,程式就比較好實現了。

源**

//遞迴實現

#include

void hanoi(int n, char a, char b, char c)

}int main()

非遞迴實現
**源****

#include

#define maxsize 100

typedef

struct

stack;

void hanoi(int n, char a, char b, char c)

while (top > 0 && stack[top].flag == 0 || stack[top].num == 1)

/*將第乙個圓盤從a移動到b,並退棧*/

if (top > 0 && stack[top].num == 1)}}

}int main()

遞迴和非遞迴實現漢諾塔問題

漢諾塔 又稱河內塔 問題其實是印度的乙個古老的傳說。開天闢地的神勃拉瑪 和中國的盤古差不多的神吧 在乙個廟裡留下了三根金剛石的棒,第一根上面套著64個圓的金片,最大的乙個在底下,其餘乙個比一 個小,依次疊上去,廟裡的眾僧不倦地把它們乙個個地從這根棒搬到另一根棒上,規定可利用中間的一根棒作為幫助,但每...

漢諾塔的遞迴和非遞迴實現

漢諾塔的遞迴和非遞迴實現 借助堆疊以非遞迴 迴圈 方式求解漢諾塔的問題 n,a,b,c 即將n個盤子從起始柱 標記為 a 通過借助柱 標記為 b 移動到目標柱 標記為 c 並保證每個移動符合漢諾塔問題的要求。輸入為乙個正整數n,即起始柱上的盤數。每個操作 移動 佔一行,按柱1 柱2的格式輸出。3a ...

漢諾塔問題的遞迴和非遞迴演算法

漢諾塔問題是源於印度乙個古老傳說的益智玩具。大梵天創造世界的時候做了三根金剛石柱子,在一根柱子上從下往上按照大小順序摞著64片 圓盤。大梵天命令婆羅門把圓盤從下面開始按大小順序重新擺放在另一根柱子上。並且規定,在小圓盤上不能放大圓盤,在三根柱子之間一次只能移動乙個圓盤。如果考慮一下把64片金盤,由一...