關於漢諾塔Hanoi的計算公式理解及其遞歸代碼


  • 什么是漢諾塔?

漢諾塔:漢諾塔(又稱河內塔)問題是源於印度一個古老傳說的益智玩具。大梵天創造世界的時候做了三根金剛石柱子,在一根柱子上從下往上按照大小順序摞着64片黃金圓盤。大梵天命令婆羅門把圓盤從下面開始按大小順序重新擺放在另一根柱子上。並且規定,在小圓盤上不能放大圓盤,在三根柱子之間一次只能移動一個圓盤

----以上來自百度百科

  • 漢諾塔移動次數計算公式

  移動次數計算公式為f(n)=2f(n-1)+1

這是一個遞歸的計算方式,可以靠想象理解一下:

i. 有3個柱子可以放,所有盤子在起始柱,還有一個目的柱和緩沖柱。在將起始柱的最大的一個盤,也就是目的柱接受的第一個盤之時。你的柱子情況應該是:起始柱子有一個盤子,目的柱子為空,緩沖柱子為(n-1)個盤子。

 

    起始柱            緩沖柱        目的柱

ii. 這時的盤子放置是一定的,因為你必須將(n-1)個盤子放在緩沖柱子,這也就是說你完成了f(n-1)次搬動,實現從起始柱子到緩沖柱子。

iii. 這時你再將起始柱的最大的盤子放到目的柱。也就是1次。

 

    起始柱            緩沖柱        目的柱

 

 iv. 這時再將緩沖柱子的(n-1)盤子盼到目的柱,(注:此時起始柱子可以用做緩沖柱子)。所以需要f(n-1)次搬運。

總結: 需要 f(n-1)+1+f(n-1)=2f(n-1)+1次搬運

用上面的公式,羅列f(1),f(2),f(3)可以得到f(n)=(2^n)-1

 

 

  • 代碼

 1 #include<stdio.h>
 2 #include<stdlib.h>
 3 
 4 static int count = 0 ;
 5 void move(char getone,char putone){
 6         count ++;
 7         printf("%c-->%c\n", getone, putone);
 8 }
 9 void hanoit(int n, char a, char b, char c){   //這里的理解是a是起始柱,c是目的柱,b是緩沖
10         if(n == 1){
11                 move(a, c);
12         }
13         else{
14                 hanoit(n - 1, a, c, b);      //在運輸除最大盤其余盤子時,將緩沖柱子作為目的柱子放置其余的(n-1)個柱
15                 printf("count :%d\n",count);
16                 move(a, c);                  //清掉(n-1)后剩下最大的,那么自然是從起始柱a放到目的柱c
17                 hanoit(n - 1, b, a, c);      //此時,剩下的(n-1)盤子時,緩沖柱b就變成起始柱了,目的柱c不變。
18         }
19 }
20 
21 int main(){int m;
22         scanf("%d", &m);
23         hanoit(m, 'A', 'B', 'C');
24         printf("count :%d\n",count);
25 
26         return 0;
27 }

 


免責聲明!

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



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