Java遞迴演算法

brucexia發表於2023-11-27

 

在程式設計中,遞迴的設計就是利用了棧的“後進先出”的思想。利用棧可以將遞迴程式轉換為非遞迴程式。

3.3.1   

遞迴是指在函式的定義中,在定義自己的同時又出現了對自身的呼叫。如果一個函式在函式體中直接呼叫自己,就稱為直接遞迴函式。如果經過一系列的中間呼叫,間接呼叫自己的函式就稱為間接遞迴呼叫。

1. 遞迴函式

例如,n 的階乘遞迴定義如下:


n 的階乘演算法如下:

public static long fact(int n)         

//n 的階乘的非遞迴演算法實現

{
         long f = 1;
         int i;
         for(i=1;i<n+1;i++) // 直接利用迭代消除遞迴
             f = f * i;
         return f;
     }

Ackerman 函式定義如下:

Ackerman 函式相應演算法如下:

public static long Ack(long m,long n)             

//Ackerman 遞迴演算法實現

{
         if(m == 0)
             return n + 1;
         else if(n==0)
             return Ack(m - 1, 1);
         else
             return Ack(m - 1, Ack(m, n - 1));
     }

2. 遞迴呼叫過程

遞迴問題可以分解成規模小且性質相同的問題加以解決。下面我們以著=名的漢諾塔問題為例來說明遞迴的呼叫過程。

n 階漢諾塔問題。假設有3 個塔座X Y Z ,在塔座X 上放置n 個直徑大小各不相同、從小到大編號為1 2 n 的圓盤,如圖3-9 所示。要求將X 軸上的n 個圓盤移動到塔座Z 上並要求按照同樣的疊放順序排列,圓盤移動時必須遵循以下規則:

1 )每次只能移動一個圓盤。

2 )圓盤可以放置在X Y Z 中的任何一個塔座。

3 )任何時候都不能將一個較大的圓盤放在較小的圓盤上。


如何實現將放在X 上的圓盤按照規則移動到Z 上呢?當n=1 時,問題比較簡單,直接將編號為1 的圓盤從塔座X 移動到Z 上即可。當n>1 時,需要利用塔座Y 作為輔助塔座,若能將放置在編號為n 上的n -1 個圓盤從塔座X 上移動到Y 上,則可以先將編號為n 的圓盤從塔座X 移動到Z 上,然後將塔座Y 上的n -1 個圓盤移動到塔座Z 上。而如何將n -1 個圓盤從一個塔座移動到另一個塔座又成為與原問題類似的問題,只是規模減小了1 ,因此可以用同樣的方法解決。這是一個遞迴問題,漢諾塔的演算法描述如下:

public static void Hanoi(int n,String A,String B,String C)

// 將塔座A 上從小到大自上而下編號為1 n 的圓盤按照規則搬到塔座C 上,B 可以作為輔助塔座

{
         if(n == 1)
             move(1, A, C);  // 將編號為1 的圓盤從A 移動到C
         else {
             Hanoi(n - 1, A, C, B);   // 將編號為1 n-1 的圓盤從A 移動到B C 作為輔助塔座
             move(n, A, C);           // 將編號為n 的圓盤從A 移動到C
             Hanoi(n - 1, B, A, C);  // 將編號為1 n-1 的圓盤從B 移動到C A 作為輔助塔座
         }
     }
     public static void move (int n, String tempA, String tempB) {
         System.out.println("move plate"+n+" from column "+tempA+" to column "+ tempB);
     }

下面以n=3 為例,來說明漢諾塔的遞迴呼叫過程,如圖3-10 所示。當n>1 時,需要3 個過程移動圓盤。

1 個過程,將編號為1 2 的圓盤從塔座X 移動到 塔座Y

2 個過程,將編號為3 的圓盤從塔座X 移動到 塔座Z

3 個過程,將編號為1 2 的圓盤從塔座Y 移動到 塔座Z


1 個過程,透過呼叫Hanoi(2,X,Z,Y) 來實現。Hanoi(2,X,Z,Y) 又呼叫自己,完成將編號為1 的圓盤從塔座X 移動到 塔座Z ,如圖3-11 所示。編號為2 的圓盤從塔座X 移動到 塔座Y ,編號為1 的圓盤從塔座Z 移動到 塔座Y ,如圖3-12 所示。

3-11  將編號為1 的圓盤從塔座X 移動到 塔座Z

3-12  將編號為2 的圓盤從塔座X 移動到 塔座Y ,編號為1 的圓盤從塔座Z 移動到 塔座Y

2 個過程完成將編號為3 的圓盤從塔座X 移動到 塔座Z ,如圖3-13 所示。

3 個過程透過呼叫Hanoi(2,Y,X,Z) 來實現圓盤移動。透過再次遞迴完成將編號為1 的圓盤從塔座Y 移動到 塔座X ,如圖3-14 所示。將編號為2 的圓盤從塔座Y 移動到 塔座Z ,將編號為1 的圓盤從塔座X 移動到 塔座Z ,如圖3-15 所示。

              本文節選自《圖解Java資料結構與演算法(微課影片版)》。



來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/18841117/viewspace-2997292/,如需轉載,請註明出處,否則將追究法律責任。

相關文章