漢諾塔遞歸問題


遞歸(recursion)

程序調用自身的編程技巧。把問題轉化為規模縮小了的同類問題的子問題。然后遞歸調用函數(或過程)來表示問題的解

  遞歸滿足2個條件:

    1)有反復執行的過程(調用自身)

    2)有跳出反復執行過程的條件(遞歸出口)

如何思考遞歸(此段摘於qmdweb的CSDN博客)

在初學遞歸的時候, 看到一個遞歸實現, 我們總是難免陷入不停的驗證之中,比如上面提及的階乘,求解Factorial(n)時,我們總會情不自禁的發問,Factorial(n-1)可以求出正確的答案么?接着我們就會再用Factorial(n-2)去驗證,,,不停地往下驗證直到Factorial(0)

對遞歸這樣的不適應,和我們平時習慣的思維方式有關。我們習慣的思維是:已知Factorial(0),乘上 1 就等於Factorial(1),再乘以 2 就等於Factorial(2),,,直到乘到 n。

而遞歸和我們的思維方式正好相反。

那我們怎么判斷這個遞歸計算是否是正確的呢?Paul Graham 提到一種方法,如下:

如果下面這兩點是成立的,我們就知道這個遞歸對於所有的 n 都是正確的。

  1. 當 n=0,1 時,結果正確;

  2. 假設遞歸對於 n 是正確的,同時對於 n+1 也正確。

這種方法很像數學歸納法,也是遞歸正確的思考方式,上述的第 1 點稱為基本情況,第 2 點稱為通用情況。

在遞歸中,我們通常把第 1 點稱為終止條件,因為這樣更容易理解,其作用就是終止遞歸,防止遞歸無限地運行下去。

 

漢諾塔問題描述為:

  有三根桿子 A,B,C。A 桿上有 N 個穿孔圓盤,盤的尺寸由上到下依次變大,B,C 桿為空。要求按下列規則將所有圓盤移至 C 桿:

         每次只能移動一個圓盤,大盤不能疊在小盤上面。

 

                                               

思路(如何移?最少要移動多少次?

首先看下基本情況,即終止條件:N=1 時,直接從 A 移到 C。

再來看下通用情況:當有 N 個圓盤在 A 上(N>1),我們怎么移動 N個圓盤到 C 杠上呢?很簡單,我們首先用將 N-1個圓盤移動到 C 上的方法將 N 個圓盤都移動到 B 上,然后再把第 N個圓盤(只有一個)移動到 C 上,再用同樣的方法將在 B 杠上的 N -1個圓盤移動到 C 上,問題解決。

Python代碼實現  (3個盤子移動過程如下)   與C語言類似      

           def hanoi(n,a,b,c):
                                          if n==1 :
                                                      print(a,'->',c)
                                              else :
                                                hanoi(n-1,a,c,b)
                                                      hanoi(1,a,b,c)
                                                      hanoi(n-1,b,a,c)
                                                    
                                         hanoi(3,'A','B','C')

                           

 

 

 


免責聲明!

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



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