漢諾塔遞歸算法C語言


2020-09-1310:42:28

@

19世紀的時候,法國數學家愛德華·盧卡斯創造了一個叫漢諾塔的神話:佛教大神梵天在創造世界的時候有點無聊,順便造了三根金剛石柱子,其中第一根柱子上堆了64塊黃金圓盤。梵天命令僧侶把所有圓盤從第一根柱子移動到第三根柱子上,且每次只能移動一片,小圓盤必須在大圓盤的上面。

梵天對僧侶說,如果全部把圓盤搬完,世界將會毀滅,所有的佛塔、廟宇、僧侶都將在烈火中化為灰燼。

 

僧侶搬完所有圓盤,需要多長時間?這個問題可以用遞歸算法來求解。

 

遞歸

遞歸算法在程序設計中被廣泛應用。根據度娘的解釋,遞歸,就是函數直接或間接地調用函數自身,直到引用對象可知。(有點像現在流行的“套娃”梗)

遞歸有一個好處,就是可以把復雜的步驟簡化成幾個簡單的步驟,從而實現對復雜問題的一步步拆解。

比如,在漢諾塔游戲中,要把n個圓盤按上述規則從A柱子移動到C柱子上,我們可以按三個大步驟去做:

1、先把上面的n-1個圓盤移動到B柱子;

 

2、把第n個(即最底層的那個)圓盤移動到C柱子;

 

3、最后把n-1個圓盤從B柱子移動到C柱子,就完成了。

 

而回到第一個步驟,怎么把n-1個圓盤按規則移動到B柱子上呢?可以繼續進行拆解,先把n-2個圓盤移動到C柱子上,然后把第n-1個圓盤移動到B柱子上,最后把n-2個圓盤從C柱子移動到B柱子……

這樣一直拆解下去,最終就可以分解為每次只移動一個圓盤的步驟了。

拆解的流程如下:

於是,就有這樣的結論:

回到最初的問題,如果僧侶需要把64個圓盤從第一根柱子移動到第三根柱子,需要搬動(2^64-1)次,假設每秒鍾搬動一次,共需要5800億年。

 1 /*漢諾塔遞歸算法*/ 
 2 #include <stdio.h>
 3 void move(int n,char x,char y)
 4 {
 5     printf("%c-->%c\n",x,y);
 6 }
 7 void hanota(int n,char A,char B,char C)
 8 //一共n個盤子,要把這n個盤子借助B柱子從A柱子全部移到C柱子 
 9 {
10     if(n==1)//遞歸出口,也就是結束的標志 
11     {
12         move(n,A,C);//當只有一個盤子的時候,直接從A柱子移到C柱子 
13     }
14     else 
15     {
16         hanota(n-1,A,C,B);//當n>1時,把(n-1)個盤子借助C柱子從A柱子移到B柱子 
17         move(n,A,C);//然后把第n個盤子從A柱子移到C柱子 
18         hanota(n-1,B,A,C);//再把(n-1)個盤子借助A柱子從B柱子移到C柱子 
19     }
20 }
21 //主函數 
22 int main() 
23 {
24     int m;
25     char a='A',b='B',c='C';
26     scanf("%d",&m);//輸入有幾個盤子 
27     hanota(m,a,b,c);
28     return 0;
29 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM