递归——自己调用自己
-
递归的定义
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