編程思想之遞歸


我以前寫過關於遞歸算法的博文,但做爲編程思想系列的文章不得再也不對它進行進一步深刻的剖析。因爲它是一種簡單、常常使用又重要的一種編程思想。java

什麼叫遞歸?

舉一個通俗的樣例: 算法

有一個8倆重的蘋果要你切成重量相等的若干份。每一份的重量不能大於1倆。你確定會想到這樣作: 編程

1.第一刀先把一個蘋果切成重量均等的2份A1和A2; 函數

2.再把當中的一份A1切成重量均等的兩份A11和A12, 把A2切成均等的兩份A21和A22。 post

3.把A11切成均等的兩份…… spa

4.直到每一小份都小於等於1倆爲止。 .net

以上的樣例就是遞歸一個模型。把一個大的事物化成若干個小的事物,每一次使用的方法都一樣。code

 

更爲專業的定義: blog

程序自身調用自身的編程技巧稱爲遞歸( recursion遞歸有直接遞歸和間接遞歸 遞歸

•直接遞歸:函數在運行過程當中調用自己。

•間接遞歸:函數在運行過程當中調用其餘函數再通過這些函數調用自己。

遞歸有四個特性:

1.必須有可終於達到的終止條件。不然程序將陷入無窮循環。

2.子問題在規模上比原問題小,或更接近終止條件;

3.子問題可經過再次遞歸調用求解或因知足終止條件而直接求解;

4.子問題的解應能組合爲整個問題的解。

 

上面的樣例中也知足以上的四點性質:

(1).終止條件是每一份的重量不能大於1倆。(2).每一次切的大小都比上一次小;(3).每一次切的方式都一樣,因此子問題可遞歸調用;(4).終於切成的每一小份也就是要求的解。

 

對上面樣例的實現:

public static void sliceApple(float weight, int times){
		if (weight <= 1) {
			//System.out.println("weight:" + weight);
		} else {
			float w = weight / 2;
			System.out.println("第" + times + "次等分的重量爲:" + w + "   " + w);
			times += 1;
			sliceApple(w, times);
			sliceApple(w, times);
		}
	}

	public static void main(String args[]) {
		sliceApple(8, 1);
	}

結果:

1次等分的重量爲:4.0   4.0

2次等分的重量爲:2.0   2.0

3次等分的重量爲:1.0   1.0

3次等分的重量爲:1.0   1.0

2次等分的重量爲:2.0   2.0

3次等分的重量爲:1.0   1.0

3次等分的重量爲:1.0   1.0


遞歸能作什麼?

將大問題分解成小問題。將複雜的問題簡單化。

使程序更易於理解。加強可讀性。

你會如何使用遞歸?

分析問題,看看問題是否屬於遞歸模型。是否能用遞歸模型解決。一個問題是否能用遞歸模型就看它是否知足遞歸的四個特性。

遞歸在調用的時候要保存調用點的信息。所以會有調用開銷。在對效率有較高要求的時候,假設能用循環解決這個問題最好不要用遞歸。因爲循環沒有調用開銷。效率會更高。



關於遞歸的不少其餘應用可閱讀以前寫的一篇文章:遞歸算法

相關文章
相關標籤/搜索