Java 遞歸的理解

在平常的開發中經常使用遞歸算法,可能由於項目的關係,或者時間的關係,亦或者壓根就沒有刨根問底的想法,平時用了也就用了,也沒有去深入的研究它的運行原理,今天在開發中跟蹤問題時發現了一個現象,所以便產生了一個疑問?

Java中遞歸的算法到底是並行的還是串行的?

在回答這個之前先了解遞歸的含義;

什麼是遞歸:遞歸二字顧名思義就是:遞過去,歸回來。所以我索性叫它做有借有還吧!

憑藉着自我認知第一映像應該是並行的,這樣的話才能保證高效,然後懷着這樣的疑問進行了測試,驗證一下自己的想法是否正確,於是就寫了以下代碼進行驗證,第二段代碼是在網上找的,這個比較典型,故借鑑引用下:

private static boolean flag = true;
private static void test1(){
	for (int i = 0; i < 10; i++) {
		if(flag && i == 6){
			flag = false;
			System.out.println("遞歸");
			test1();
		}
		System.out.println("i = " + i);
	}
}

public static void test2(int n) {
    System.out.println("1-lexe:" +  n);   //#1
    if (n < 3)
        test2(n + 1);
    System.out.println("2-lexe:" +  n);   //#2
}

可以看到,代碼很簡單,只要是爲了驗證結果

擔心CPU的時間片搶佔資源的關係,進行了幾十次的運行,結果很意外,真的很意外!!!

第一段代碼的結果:
i = 0
i = 1
i = 2
i = 3
i = 4
i = 5

遞歸
i = 0
i = 1
i = 2
i = 3
i = 4
i = 5
i = 6
i = 7
i = 8
i = 9

i = 6
i = 7
i = 8
i = 9


第二段代碼的結果:
1-lexe: 1
1-lexe: 2
1-lexe: 3
2-lexe: 3
2-lexe: 2
2-lexe: 1

test2方法流程解讀:
首先, main() 調用了函數 test2(1) ,於是test2(1)中形參 n 的值是 1, 故打印語句 #1 輸出了:1-lexe:1  。
然後,由於 n < 3 ,( 第 2 級 )的test2(n+1)被調用. 此時n+1=2,故打印語句 #1 輸出了:1-lexe:2。
然後,由於 n < 3 ,( 第 3 級 )的test2(n+1)被調用. 此時n+1=3,故打印語句 #1 輸出了:1-lexe:3。
由於此時,n=3 , 不再執行if語句。
然後執行 #2 語句 , 因爲此時 n 的值爲 3 , 故打印語句 #2 輸出了: 2-lexe:3 。  ---------------------------這時完成了一個“遞過去”

此時函數調用完成         
現在函數需要“歸回來” , 回到最後一次調用函數的地方 , 即 n+1=2 的地方 , 故打印語句 #2 輸出了:2-lexe:2。

再返回上一級調用的地方 , n =1 的地方 , 故打印語句 #2 輸出了:2-lexe:1。-----------------------------完成了一個“歸回來“

其實他的”歸回來“的切入點就是函數的調用點 ,獲取此處的參數值 , 一級一級的往外突圍就出來了。

總結:通過以上結果可以得出,遞歸本質是串行的,它的工作原理是一個由外到裏、由裏到外串行運行的過程,直到所有的由外到裏“遞出去”再由裏到外全部“歸回來”,該過程也就結束了。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章