理解遞迴 Recurtion

LeoooY發表於2019-02-21

In order to understand recursion, one must first understand recursion.

To Iterate is Human, to Recurse, Divine.

遞迴的定義

子程式或者函式直接或者間接呼叫自身。 遞迴是一種描述問題解決問題的基本方法,相比(迴圈)之下遞迴寫出的程式碼可讀性更好,不過效能上並沒有優勢。此外,很多演算法的實現都離不開遞迴。

遞去歸來,是描述問題,時解決問題。

//例如A()函式內部呼叫了自己,叫做
//直接遞迴呼叫
function A(){
  A();
}

//間接遞迴呼叫
function B(){
  C();
}

function C(){
  B();
}

//尾遞迴
function A(){
  return A()
  //作為return返回時呼叫,稱為尾遞迴
}
複製程式碼

遞迴的基本結構:

  • 遞迴項&遞迴關係 (Recursive Case) 描述大問題如何分解為小問題,也稱為遞迴體
  • 遞迴邊界條件(Base Case) 停止遞迴的條件,也稱為遞迴出口
// 虛擬碼
function recurtion(sth){
    if(stopRecurtion === true){ //base case
        return
    }else{                      //recurtion case
        sth=expression  //與子問題的遞迴關係
        recurtion(sth)  //呼叫自身
    }
}

recurtion(sth)
複製程式碼

遞迴呼叫棧 The Call Stack

也稱為遞迴工作棧,層層向下遞迴,返回次序正好(與呼叫次序)相反
即遞迴中的每個子函式的呼叫是放入一個呼叫棧來執行,後進先出,所以遞迴到最深的子問題時開始逐層向上返回。

遞迴的一些簡單應用

  • 階乘
    • 遞迴演算法
    • 非遞迴演算法
  • 斐波那契豎列求解
    • 遞迴演算法
    • 非遞迴演算法
  • 迴文串
    • 遞迴演算法
    • 非遞迴演算法

小結

應用遞迴解決的思路:

  • 找到最小子問題
  • 找到遞迴關係,即如何從頂層到達下一層的條件(關係)
  • 寫出最小子問題的解決過程,在恰當的時候呼叫自己(實現遞迴關係)
  • 遞的分析可以將問題關係描述清楚,歸的分析也是難點,是解決問題的關鍵
  • 理解遞迴的執行棧可以幫助理清楚歸的過程

參考

相關文章