7 17 漢諾塔的非遞迴實現 25分

2022-06-10 13:27:07 字數 2796 閱讀 2895

參考:

的和的。

簡單說一下我理解到的方法吧

第一步是判斷輸入的n是奇數還是偶數,若為奇數,則按順時針以acb的順序擺成品字型,若為偶數,則按順時針以abc的順序擺成品字型。(參考下圖)

第二步將序號為1(最小)的盤,按順時針放到下乙個字母。假如以abc順序順時針擺放時,若1盤在a,則將它移動到b,若在b則移動到c……

第三步處理剩餘兩個字母(1盤此時不在的那兩個字母),暫且稱為x和y。可能會出現如下幾種情況:

1)x和y都有盤,此時他們頂層的盤必能比較出大小,那麼這時候將小的盤移動到大的盤上面,結束。

2)x和y都沒盤,不用做任何處理。(比如輸入的n為1的時候就會出現這種情況)

3)x和y乙個有盤,乙個沒盤,這時候將有盤的一邊的盤移動到沒有盤的一邊,結束。

只要我們迴圈執行第二步和第三步就能完成漢諾塔的非遞迴實現。

下面是我的ac**:

1

//非遞迴ac**2//

用cout最後乙個測試會超時,改為printf就ac了

34 #include 5 #include

6 #include 7 #include 8 #include 9

using

namespace

std;

10int n;//

輸入的盤子數

1112

class stack_//

「三根柱子」的型別

1316 ~stack_() {}

17void push(int

k)18

21int

pop()

2228

public:29

char

name;

30int r;//

指標31

int h[10000

];32

};33 stack_ s[3];//

將三根柱子定義為陣列,方便操作

3435

bool is_over(int cnt)//

判斷移動次數有沒有超過2^n-1

3642

43void move(char a, char b, char c)//

移動函式主體

4463 temp1 = s[(k + 1) % 3

].pop();

64 temp2 = s[(k - 1) % 3

].pop();

65if ((temp1 != 0 && temp2 != 0)&& (temp1 < temp2) || temp2 == 0 and temp1 != 0)//

temp1 移動到 temp2 的情況

667576}

77else

if (temp1 == 0 && temp2 == 0)78

83else

8493

}94 i++;//

注意在末尾將i的值加1,實現0,1,2的輪迴95}

96else

97101

}102

//cout << endl << cnt << endl;

103}

104105

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

介面107

115 move(a, b, c);//

呼叫move開始進行移動

116}

117118

intmain()

119

再附加個遞迴實現的:

1

//遞迴實現

2 #include 3 #include

4 #include 5

6using

namespace

std;

7void hanoi(int n, char a, char b, charc)8

14else

1521}22

23int

main()

24

對於遞迴演算法我的個人理解:

首先將初始盤子看成是n-1的整體和最下面的最大一塊的組合體。

hanoi(n-1

,a,c,b);

cout << a <

->

"<< c <

hanoi(n-1,b,a,c);

hanoi(n,a,b,c,)中a為初始位置,c為目標位置,上述**第一步目的是將n-1整體從a移動到b,所以呼叫hanoi(n-1,a,c,b)。依此類推,第二步是要把最大一塊從a移動到c,所以也可寫成hanoi(1,a,b,c),第三步同理。

那麼為什麼hanoi(n-1,a,b,c)可以實現將上面的n-1個盤從a移動到b呢?

我的理解:

當n=2時,即n-1為1的時候,這個函式顯然是可以實現這一目標的。當n=3時n-1就為2了,這個時候呼叫hanoi(n-1,a,b,c)其實就是呼叫hanoi(2,a,b,c),那麼我們剛剛已經確定引數為2的時候是可以達到目的的,那麼可以推出,n為3的時候也可以達到目的(因為他是借助n-1=2時的函式實現的),於是就可以繼續往後面推斷出n為任何數字的時候都可以實現這一功能。

7 17 漢諾塔的非遞迴實現 25分

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

7 17 漢諾塔的非遞迴實現 25 分

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

5 17 漢諾塔的非遞迴實現 25分

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