漢諾塔算法是C語言遞歸算法調用的一個經典算法,對學習和理解C語言的遞歸函數調用有一定的幫助。
漢諾塔遞歸算法思路:
1. 如果只有一個盤子,那么直接從柱子1移動到柱子3
2. 如果有 >1 個盤子,那么先把 n-1 個盤子從柱子1移動到柱子2 (想要讓最底下一個移動到從柱子1移動到柱子3,一定會有這一步驟,就是除了最底下的那個柱子,其他都按照順序排列在柱子2中)
再把第n個盤子從柱子1移動到柱子3
最后再把n-1個盤子從柱子2移動到柱子3
代碼:
1 #include <stdio.h>
2
3 int count = 1; 4 // 因為傳送過來的是字符串不是字符,所以形式參數要用char*而不是用char
5 void hannuota(int n, char* a, char* b, char* c) { // 盤子數,盤子原來所在柱子,借助的柱子,目的地所在柱子
6 if (n == 1) { 7 printf("%d: %s -> %s \n", count, a, c); // 當n==1的時候,直接從柱子1移動到柱子3
8 count++; 9 } 10 else { 11 hannuota(n - 1, a, c, b); // 第一步需要把 n-1 個盤子從 柱子1 借助 柱子3 移動到 柱子2
12 printf("%d: %s -> %s \n", count, a, c); // 第二步把 柱子1 剩下的最大的那個從 柱子1 移動到 柱子3
13 count++; 14 hannuota(n - 1, b, a, c); // 第三步把 柱子2 中的 n-1 個盤子從 柱子2 借助 柱子1 移動到 柱子3
15 } 16 } 17
18 int main() { 19 int n = 0; 20 printf("請輸入漢諾塔的盤子數:"); 21 scanf("%d", &n); 22 hannuota(n, "柱子1", "柱子2", "柱子3"); 23 return 0; 24 }
運行結果:
這個例子中,使用遞歸確實把復雜的問題簡化了,但是在C語言中,使用遞歸經常會遇到stackoverflow也就是棧溢出的問題,所以大家謹慎使用。甚至有時候使用遞歸會降低代碼的執行效率,那么就可以使用循環代替遞歸來求解,遞歸和循環一個相似的地方就是有重復執行的代碼塊,但是遞歸的更注重:大事化小,把一個大的問題,逐步拆成小問題一個個調用,類似這類問題比如求n的階乘這個算法也很適合使用遞歸方法求解,就是最后的結果是建立在之前結果的累加,或者前面的思路很清晰而后面看上去復雜了但使用的是和前面一樣的思路,這兩種情況就很適合用遞歸。這個使用遞歸求解漢諾塔的算法在一些大廠筆試題中是可能出現的,大家感興趣的可以自己動手敲敲代碼,實踐總是有更深的感悟的~更多的大廠筆試代碼就在 《劍指offer》~
參考資料:
https://www.cnblogs.com/ruofengzhishang/articles/1939444.html