1. 程式人生 > 其它 >漢諾塔和遞迴

漢諾塔和遞迴

技術標籤:演算法

漢諾塔與遞迴

1.漢諾塔

規則如下:

在小圓盤上不能放大圓盤,在三根柱子之間一次只能移動一個圓盤.

圓盤從上到下一次標記為1、2、3.....n.

情況1:假設只有1個圓盤則只需要從A移動到C,總共移動1次。

情況2:假設只有2個圓盤則只需要把第1個移動到B,然後把第2個移動到C,最後再把第1個移動到C,總共移動3次。

情況3:**假設有3個圓盤則只需要把第1個移動到C,把第2個移動到B,再把第1個移動到B,接著把第3個移動到C,再把第1個移動到A,再把第2個移動到C,最後把第1個移動到C,總共7步。

......

可以從假設有2個圓盤和假設有3個圓盤這兩種情況的移動步驟中總結出一個規律:

類比情況3和情況2,可以把情況3步驟簡化為3步,想象第1個和第2個是一個整體,然後與第3個組成2個圓盤就變成了情況2,第一步把第1個和第2個這個整體放倒B柱上,第二步把第1個放到C柱上,第三步把第1個和第2個這個整體放到C柱上就完成。

可能會有疑問為什麼把第1個和第2個看做一個整體,注意我們這裡是簡化它的步驟,回到情況3,執行到第3步的時候是不是就相當於類比中第一步把第1個和第2個這個整體放倒B柱上。情況3執行到第4步的時候就相當於類比情況第二步把第1個放到C柱上。情況3中剩下的第567步相當於類比情況的第三步。

也就是說無論有多少個圓盤都可以像情況三中簡化為總共三個步驟。

那麼我們可以根據這觀察三步列出一個數學公式,假設n個圓盤移動F(n)次。還是用情況3來舉例子。那麼第一步把第1個和第2個這個整體放倒B柱上需要移動F(3-1)次,第二步把第1個放到C柱上,因為只有一個也只移動1次,第三步把第1個和第2個這個整體放到C柱上需要移動F(3-1)次。那麼總共移動多少次結果為:

F(3)=F(3-1)+1+F(3-1)

化簡得:F(3)=2*F(2)+1,但是這裡我們不知道F(2)和F(3)等於多少。但是我們知道圓盤只有一個時就是移動一次即F(1)=1。那麼我們可以計算情況2需要多少次,F(2)=F(2-1)+1+F(2-1)化簡為F(2)=2XF(1)+1,因為F(1)=1,代入得F(2)=3。得到了F(2)我們就可以得到F(3)=2X3+1=7次。

那麼當圓盤為n個時就可以根據三個步驟同理列出公式

F(n)=F(n-1)+1+F(n-1)=>F(n)=2*F(n-1)+1

又因為一個圓盤為1次,兩個圓盤為3次,3個圓盤為7次,根據1,3,7數字規律得出了一個快速計算漢諾塔次數的公式:2^n-1.

2.遞迴

編寫程式計算漢諾塔移動次數

我們可以根據公式:F(n)=2*F(n-1)+1利用遞迴原理來程式設計實現計算。把return看做=號,又因為計算機不知道F(0)等於多少,何時終結程式,所以加一個if條件語句告訴計算機F(0)=0。然後遞迴也涉及到了棧的原理,外部呼叫這個f函式時會把這個函式壓入棧,然後當return 2xf(n-1)+1時又呼叫了f函式,所以先把當前的函式再次壓入棧,直到n==0時,計算機知道F(0)=0了,那麼也就知道F(1)=1,然後就又知道F(2)....F(n),在這個過程中被壓入棧的函式也依次彈出來了。

int f(n){
   if(n==0)
    return 0;
  else
    return 2*f(n-1)+1;
 }