Java 遞迴概念與實戰

2021-09-20 02:02:33 字數 2357 閱讀 9818

本文主要介紹的遞迴演算法。

構成遞迴需具備的條件:

1:子問題須與原始問題為同樣的事,且更為簡單(簡單點理解類似 累加或者累乘)

2:不能無限制地呼叫本身,須有個出口,化簡為非遞迴狀況處理。(也就是需要將結果返回出去,無限的自己呼叫自己沒有意義,因為演算法的本質是為了提高效率)。

九九乘法表:

對於大多數人來說九九乘法表這種都是信手拈來朗朗上口的基本算術法則背起來還是蠻麻溜的,那麼從編碼的角度下我們該如何思考以及編寫**?首先是九九乘法的效果圖:

九九乘法表

這裡首先請摒棄我們的傳統計數思維,讓我們從開發者的角度去思考分析這個乘法表現象。通過觀察可以發現,這個乘法表的橫向以及縱向的數量 與執行次數都是一樣的。比如:第乙個計算順序(橫向以及縱向)也就是第乙個位置,它只執行了一次:1 * 1;第二個計算順序(橫向以及縱向)也就是 1 * 2 、2 * 2 ,共計執行了兩次,後面的以此類推(這裡有乙個次數累加的過程)。在不考慮遞迴的情況下,我們可以使用for迴圈去進行操作,既然上面已經清楚了,我們首先可以寫乙個for迴圈:

這個for迴圈大家一看便知,就是執行了9次。但是這個距離完成九九乘法表還有很大的距離。根據上面的現象分析出來的結論,還需要多執行一步(也就是:橫向以及縱向的數量 與執行次數 都是一樣的)因此我們還需要巢狀乙個for迴圈(巢狀的目的就是讓橫向以及縱向的數量 與執行次數變成一樣),讓其進行乘法的操作,所以,最終版本的九九乘法表使用for迴圈完成的**就是這樣:

九九乘法表

那麼,我現在能不能只用乙個for迴圈,就將九九乘法表給表現出來?

首先我們寫個測試的,從9開始:

測試9然後寫個六六乘法表做測試:

測試6我相信上面2個迴圈只是用來幽默一下的,但是我們可以發現,既然這種乘法表所做的事情都是乘法那麼,現在我們可以用遞迴演算法進行操作(也就是方法呼叫方法本身),**如下:

遞迴那麼,它的呼叫方式如下(這裡的m 代表的是method 也就是圖上的 digui ( int i )):

遞迴呼叫方式

我們知道每乙個方法的呼叫都會產生乙個棧幀,壓入到方法棧(棧,是 先進後出),當遞迴呼叫的時候,方法棧中棧幀的圖示和上圖類似。

去掉方法中棧幀的引用關係更加直觀,如下圖所示:

遞迴棧結構圖

簡化掉相應的方法呼叫最後執**況如上圖所示,注意 i 一直在變  j每次都是從1開始 然後遞增到和i相等。

最終的結果就是:

遞迴為了更好的理解遞迴,這裡在舉乙個我們小學聽到的故事。有一天,老師布置了一道題,1+2+3······這樣從1一直加到100等於多少。然後7歲的高斯通過快速對稱加分給出了答案:5050。那麼用**的方式該如何進行操作?其實只需定義乙個變數讓其滿足條件然後對其進行累加即可,下面就是通過兩種迴圈進行的操作累加:

迴圈累加

那麼,可以通過遞迴來做嘛?當然可以,前面也說了構成遞迴需具備的條件之一就是子問題須與原始問題為同樣的事,且更為簡單(這裡同樣的事情就是 累加),因此我們可以這樣寫:

遞迴累加

總結:

對於乙個複雜的問題,把原問題分解為若干個相對簡單類同的子問題,繼續下去直到子問題簡單到能夠直接求解,也就是說到了遞推的出口,這樣原問題就有遞推得解。另外遞迴與迴圈有一定的相似性,都是滿足條件進行符合條件內的操作。

如果這篇文章對你有幫助,希望各位看官留下寶貴的star,謝謝。

遞迴與分治 實戰

例1.整數劃分問題 將正整數n表示成一系列正整數之和。如 p 6 有11種劃分 6 5 1 4 2 4 1 1 3 3 3 2 1 3 1 1 1 2 2 2 2 2 1 1 2 1 1 1 1 1 1 1 1 1 1 從上述可以看出 1 對於p 6 來說,其都是不大於6的數字進行相加得到。2 以5...

遞迴演算法介紹及Java應用實戰

什麼是遞迴演算法 遞迴演算法是把問題轉化為規模縮小了的同類問題的子問題,然後遞迴呼叫函式 或過程 來表示問題的解。乙個過程 或函式 直接或間接呼叫自己本身,這種過程 或函式 叫遞迴過程 或函式 遞迴過程一般通過函式或子過程來實現。遞迴方法 在函式或子過程的內部,直接或者間接地呼叫自己的演算法。遞迴其...

實戰Java高併發程式設計之概念

學習高併發你必須知道的幾個重要的概念 1.同步 synchronous 和非同步 asynchronous 同步和非同步是對方法的呼叫而言的 同步呼叫時,會等待呼叫的方法完成以後才能繼續執行這個方法。非同步呼叫的時候會瞬間的返回,但是並不是表示這個請求已經完成了,但是會在後台起乙個執行緒去執行接下來...