遞歸——自己調用自己
-
遞歸的定義
1:故事:
大家都聽過老和尚講的故事吧,從前有座山,山上有座廟,廟里有個老和尚,老和尚在講故事給小和尚聽:"從前有座山,山上有座廟,廟里有個老和尚,老和尚在講故事給小和尚聽:'從前座山,山上有座廟,廟里有個老和尚,老和尚在講故事給小和尚聽.........",
這就是生活中一個用遞歸形成的故事。
2:德羅斯特效應
3:定義:遞歸(Recursion),是指在函數的定義中又調用函數自身的方法。
遞歸分為遞推、回歸兩個過程,遞推過程把數據不斷地壓進堆棧,我們知道堆棧是先進后出,當遞推到初始條件時,開始回歸,調取保存在堆棧中的數據,最好得到所求結果。
-
遞歸求階乘
我們知道階乘的算法,例如求5!=5*4*3*2*1,運用遞歸即我們要知道5!的值,必需先知道5!——>4!——>3!——>2!——>1!,而所有階乘的初始條件都為1!=1,此過程稱為遞推,我們總共遞推了4次,知道初始條件1!=1,我們開始回歸,1!——>2!——>3!——>4!——>5!,具體步驟如下圖所示:
C#:
private static int ii = 0;//遞推過程計數
private static int jj = 0;//回歸過程計數
static long Recusion(long n)
{
long lngReturn = 1;
if (n >= 1)//判斷條件,防止無限遞歸(遞歸結束條件)
{
ii++;
Console.WriteLine("第" + ii + "次遞推:n=" + n);
lngReturn = n * Recusion(n - 1);
jj++;
Console.WriteLine("第" + jj + "次回歸:lngReturn=" + lngReturn);
}
return lngReturn;
}
VB.NET:
'遞歸求階乘
Function Recusion(ByVal n As Long) As Long
Dim lngReturn As Long = 1
Static ii As Integer = 0 '遞推次數計數
Static jj As Integer = 0 '回歸次數計數
If (n >= 1) Then
ii += 1
Console.WriteLine("第" & ii & "次遞歸過程:n=" & n)
lngReturn = n * Recusion(n - 1)
jj += 1
Console.WriteLine("第" & jj & "次回歸過程:lngReturn=" & lngReturn)
End If
Return lngReturn
End Function
運行結果顯示如下:
使用普通方式求遞歸:
C#:
static long P_Recusion(long n)
{
long lngReturn = 1;
for (int i = 0; i < n; i++)
{
lngReturn *=(i+1) ;
}
return lngReturn;
}
VB.NET:
Function P_Recusion(n As Long) As Long
Dim lngReturn As Long = 1
For i = 1 To n
lngReturn *= i
Next
Return lngReturn
End Function
從以上兩種方式求階乘我們可看出:
(1):遞歸的優點:歸方法只需少量的程序就可描述出解題過程所需要的多次重復計算,大大地減少了程序的代碼量,邏輯簡單。
(2):遞歸的缺點:遞歸方法的運行效率不高。
-
遞歸求最大公約數
1:最大公約數:最大公因數,也稱最大公約數、最大公因子,指兩個或多個整數共有約數中最大的一個。
2:例如求45,30的最大公約數。最常用的即:輾轉相除法。即用45/30,若不整除,則用35/(兩數的余數),直到余數為0。
C#:
//輾轉相除法求最大公約法
static int gcd(int m, int n)
{
//m保存較大數,n保存較小數
if (m<n)//若m<n,則交換兩數
{
int temp=0;
temp = m;
m=n;
n=temp;
}
int r = m % n;
if (r == 0)//兩數整數整除,則返回較小數n
{
return n;
}
else//兩數不整數,則輾轉相除,知道余數為0
{
return gcd(n, r);
}
}
VB.NET:
'輾轉相除法求最大公約數
Function gcd(m As Integer, n As Integer) As Integer
'm保存較大數,n保存較小數
If (m < n) Then '若m<n,則交換兩數
Dim temp As Integer = 0
temp = m
m = n
n = temp
End If
Dim r As Integer = m Mod n
If (r = 0) Then '兩數整數整除,則返回較小數n
Return n
Else '兩數不整數,則輾轉相除,知道余數為0
Return gcd(n, r)
End If
End Function