談談遞迴

放白鹿於青崖code發表於2020-11-07

從遞迴開始講起

首先我們要明白什麼是遞迴?
遞迴演算法在電腦科學中是指一種通過【重複將問題分解為同類的子問題而解決問題】的方法。 簡而言之,就是將一個規模大的問題,不斷分解為同型別的規模小的子問題。規模一旦小了,也就容易求解了。在進行分解的時候,分解到哪裡/什麼時候可以停止呢?到規模小到可以直接(或極其容易)得解的情況,就可以了。
遞迴求解問題的思路在於,在大問題分解到了為最小規模問題時,可以求得最小規模問題的解,這個時候再返回去,層層返回,最終就可以求得大問題的解了。
那麼問題來了,如何將規模大的問題分解為規模小的問題呢?
在程式設計當中,遞迴演算法是這樣實現的:通過不斷呼叫自身方法,只需改變其中的引數,使引數按一定規則往小的方向變化,就能做到將問題規模縮小化。 這也正是遞迴的核心所在。

遞迴的套路

遞迴演算法發展至今可以說已經趨於規範化了,可以提煉和總結出它的結構組成。縱使遞迴的題目型別很多,具體內容也各有不同,我們只要掌握了遞迴演算法的內在核心,再認識遞迴的模板套路,就能比較輕鬆地求解問題。

  1. 細讀題目,抓住需求,瞭解要實現的具體功能
    就像拿到一道數學題一樣,我們首先需要品讀題目,弄清楚這一題目要我們幹嘛,讓我們求些什麼。然後對這一題目進行思考,可以用怎麼樣的數學方法進行解答,這個解決的方法,就是要實現的具體功能。

  2. 遞迴,規模縮小,寫出達到最小規模問題的條件
    我們遞迴的思路是不斷將問題規模縮小化,但是最終,必須要有一個終止的條件,(無窮無盡的縮小沒有意義),這個終止的條件,就是到達最小規模問題的條件。

  3. “推卸責任”,呼叫自身方法,改變引數使規模變小,剩下的交給他們
    我們要不斷縮小引數的範圍,在保證問題型別不改變的情況下,只讓規模變小。我們只需完成一點點事情(看具體題目而定),然後將剩下規模的子問題,交給呼叫了的改變了引數範圍的自身方法即可。 因為有第二點的終止條件限制,因此在到達最小規模子問題時,呼叫就會停下來。

遞迴模板參照

這是最簡單、最一般性的遞迴模板:

public void RecursionMethod(引數) {
    if (終止條件) {
        return;
    }
    RecursionMethod(規模小的引數);
}

但是在實際程式設計題目中,很多遞迴在呼叫之前或者呼叫之後,都會有一些邏輯上的處理(這種處理因具體題目而異)。
因此可以將模板再細緻化:

public void RecursionMethod(引數) {
    if (終止條件) {
        return;
    }
    
    邏輯運算...
    RecursionMethod(規模小的引數i);
    邏輯運算...
    RecursionMethod(規模小的引數j);
     ……
}

寫在後面

模板的使用其實是在自身掌握了這個知識點後才起到給人簡易、便利的效果,是一個錦上添花的作用。
最重要的依然在於對演算法的理解和思考。對於遞迴的介紹,希望讀者能夠耐心看看文章的文字敘述部分,加深對於遞迴的理解。 小編囿於水平,這裡談的也只是遞迴的簡單分析,望讀者們批評指正。後續會舉出具體的例子來對遞迴做進一步的剖析,漢諾塔的例子會在後文著重介紹。

相關文章