關於漢諾塔的一些個人看法(遞迴)
漢諾塔(又稱河內塔)問題是源於印度一個古老傳說的益智玩具。大梵天創造世界的時候做了三根金剛石柱子,在一根柱子上從下往上按照大小順序摞著64片黃金圓盤。大梵天命令婆羅門把圓盤從下面開始按大小順序重新擺放在另一根柱子上。並且規定,在小圓盤上不能放大圓盤,在三根柱子之間一次只能移動一個圓盤。(此處為百度百科給出的關於漢諾塔的介紹)
漢諾塔的問題簡而言之就是存在3個長度一致處於同一水平面的圓柱(圓柱從左到右分別為A(起始柱)、B(輔助柱)、C(目標柱)),而剛開始有n個大小不一的圓盤穿入在A(起始柱)這個柱子內,從下往上依次變小(最上方圓盤最小,最下方圓盤最大),這個漢諾塔遊戲要求我們每次只能移動3個柱子中的一個且每次只能移動一個圓盤,並且移動到其他圓盤時也需保證穿入圓柱的圓盤是按照從大到小一次豎直排列的,最終的目的則是保證目標柱C達到有n個圓盤的數目(即達到開始時起始柱的狀態)。
從上可知漢諾塔的問題歸根到底就是要使用大事化小的方式,即遞迴的方式,根據遞迴的定義需要設定出口語句和遞迴關係語句 問題在於如何找到出口,如何才算是完成漢諾塔,出口問題毫無疑問是最小的圓盤移動到了目標柱;那麼從a(起始柱)移動到c(目標柱)中還是從b(輔助柱)移動到c中去?如果僅剩最後一個最小的柱子,說明前n-1柱子已經移動到了c中,剩下兩個柱子都是可以放最後一個圓盤的,為了理解方便我們將最後一個圓柱放在a中,出口問題解決後,我們考慮關係問題,即可以遞迴為圓盤經a過b放置到c中,移動到b盤我們就需要依靠c,移動到c盤我們就需要依靠a(遞迴問題主要思考大體方向,然後設定出口語句即可)
設計的c語言如下:
#define _CRT_SECURE_NO_WARNINGS 1 #include<stdio.h> #include<stdlib.h> void Move(char source, char dest) { printf("%c -> %c\n",source,dest); } void Hanno_Tower(int n ,char A,char B,char C){ if (n == 1) { Move(A,C); } else { Hanno_Tower(n - 1, A, C, B); Move(A, C); Hanno_Tower(n - 1, B, A, C); } } int main() { int num = 0; printf("請輸入需要移動圓盤層數:"); scanf("%d",&num); Hanno_Tower(num,'A','B','C'); system("pause"); return 0; }
這裡面存在一個過程關係問題:
我們設定遞迴函式表明次問題使數量為n-1即已經被解決了一個,設定定義時A,B,C三者的位置分別代表起始柱、輔助柱、目標柱;函式體中的Hanno_Tower(n - 1, A, C, B);表明A經C到B也就是我上面所說的(A通過B到達C),然後Move(A,C);程式碼是為了圓盤走法的補充,我們主旨在於由A經B到C,這裡MOV以下就是保證A->C的路徑;Hanno_Tower(n - 1, B, A, C);程式碼則表示B經A到C,之後無需加入A->B,因為上面程式碼已經實現。
以上就是我對漢諾塔問題的一些個人看法,如果有什麼問題請各位看官指正(●'◡'●)!!!