這幾天在家看完了《程式設計師的數學》這本書,裡面的內容深入淺出比較容易理解,將乙個個晦澀的數學概念用經典例題講解,使人不覺得枯燥。這本書看第一遍有兩處地方卡殼,不是很懂,再看第二遍大致能捋清了,其中乙個就是我這篇文章要講的經典漢諾塔問題。
漢諾塔是乙個由數學家愛德華·盧卡斯(edward lucas)於2023年發明的遊戲,該遊戲中包含了三根細柱(a、b、c),a柱上套有6個圓盤,這些圓盤大小各異,按從大到小的順序自下而上擺放,如圖1所示:
現在要把套在a柱子上的6個圓盤全部轉移到b柱上,並且在移動圓盤時必須遵守以下規則:
將乙個圓盤從一根柱子移到另一根柱子,算移動「1次」,那麼,將6個圓盤全部從a移到b最少需要移動幾次呢?
分析思路:我們先考慮小的漢諾塔,並找出其中的規律。首先,我們假設將n個圓盤從a移到b最少需要f(n)次。
當n = 0時,我們不需要移動, f(0) = 0;
當n = 1時,f(1)即將1個圓盤從a移到b,我們可以直接移動過去,所以f(1) = 1;
當n = 2時,我們要先把第乙個圓盤從a柱移到c柱,再將第二個圓盤從a柱移到b柱,最後再將c柱上的圓盤移到b柱,總共移動了三次,所以f(2) = 3;
當n = 3時,第一步我們先將a上面的兩個圓盤移動到c,這個過程就相當於f(2)的過程,只是f(2)的中間柱是c,而這一過程的中間柱是b,總的來說,中間柱就是除了始發柱和目標柱以外的那根柱子,作用是用來暫時放置那些小圓盤的;第二步將最下面那個圓盤移到b;最後一步將c上的兩個圓盤移到b,和第一步類似。這整個過程其實就是先實施乙個f(n - 1)
的方案,將起始柱上面的那(n - 1)個圓盤移動到中間柱上,再將最底層的那個圓盤移動到目標柱上,最後再實施乙個f(n - 1)
的方案,將中間柱上的那(n - 1)個圓盤乙個個移到目標柱上。因此f(3) = f(2) + 1 + f(2) = 7
。
這就是一種遞迴,f(n) = 2f(n - 1) + 1 = 2**n - 1
,所以要把套在a柱子上的6個圓盤全部轉移到b柱,需要f(6)次,f(6) = 2**6 - 1 = 63
。具體的移動方案還應該加入幾個引數,即起始柱x、中間柱y、目標柱z,函式設為hanoi(n, x, y, z)
,具體實施**如下:
#include#includevoid hanoi(int n, char x, char y, char z);
void hanoi(int n, char x, char y, char z)
else
} int main(void)
執行一下吧,看看你得到的結果。 經典漢諾塔問題分析
漢諾塔 於印度傳說的乙個故事,上帝創造世界時作了三根金剛石柱子,在一根柱子上從上往下從小到大順序摞著64片 圓盤。上帝命令婆羅門把圓盤從下面開始按大小順序重新擺放在另一根柱子上。並且規定,在小圓盤上不能放大圓盤,在三根柱子之間一回只能移動乙個圓盤,只能移動在最頂端的圓盤。有預言說,這件事完成時宇宙會...
經典遞迴問題 漢諾塔
漢諾塔 漢諾塔問題第一次接觸時就感覺非常有趣,但是由於當時知識有限不能深刻地理解遞迴的含義,所以沒能繼續深究,現在來談一談吧。題目描述 漢諾塔 於印度傳說的乙個故事,上帝創造世界時作了三根金剛石柱子,在一根柱子上從上往下從小到大順序摞著64片 圓盤。上帝命令婆羅門把圓盤從下面開始按大小順序重新擺放在...
經典問題 漢諾塔(遞迴)
c 如下 法國數學家愛德華 盧卡斯曾編寫過乙個印度的古老傳說 在世界中心貝拿勒斯 在印度北部 的聖廟裡,一塊黃銅板上插著三根寶石針。印度教的主神梵天在創造世界的時候,在其中一根針上從下到上地穿好了由大到小的64片金片,這就是所謂的漢諾塔。不論白天黑夜,總有乙個僧侶在按照下面的法則移動這些金片 一次只...