1.函数的递归
函数递归:函数中调用自己,这样就会进入一直调用自己的套娃行为,所以递归一般会有一个出口,这个出口的目的就是停止调用自己
2.递归的定义:递归本身就是一个循环。
3.递归的思想:越来越接近已知值。
4.递归的总结:1)通过自己调用自己吧复杂的逻辑简单化,可以求得最终结果;
2)递归要有开始条件,也要有一个结束条件;
3)有一种递归的逻辑运算。
如果没有结束条件的话,函数会一直调用自己,不断的开辟内存空间,最终会导致内存溢出
//递归:在函数中自己调用自己
static int getNum2(int num)
{
//一直在开辟空间,栈会溢出。
return getNum2(num);
}
getNum2(10);
2.函数的递归案例:
1)斐波那契数列\
- 提示:已知 1 1 2 3 5 8 13 21 34... 我们发现后面数是前两个数的和,我们称这种数列为斐波那契数列
- 题目要求:输入n,求出n项的斐波那契数列
- 例:输入4 输出 1 1 2 3
关系式:f(n) = f(n-1)+f(n-2)
Console.WriteLine("请输入一个数字:");
int n = Convert.ToInt32(Console.ReadLine());
for(int i = 1; i <= n; i++)
{
Console.WriteLine(printShulie(i));
}
static int printShulie(int num)
{
//终止条件如果是1 或2的时候返回1
if(num == 1|| num == 2)
{
return 1;
}
else
{
return printShulie(num - 1) + printShulie(num - 2);
}
}
2)有关系式1 * 1+2 * 2+3 * 3+...k * k<2000,编一个程序,求出满足此关系的k的最大值,利用递归和循环解决这个问题
//求关系式:
f(k) = 11+22+33+...+(k-1)(k-1)+kk;
f(k-1) = 11+22+33+...+(k-1)(k-1)
f(k) = f(k-1)+kk
出口就是f(1) = 1
static int getFK(int num)
{
if (num == 1) return 1;
return getFK(num - 1) + num * num;
}
int i = 1;
while (true)
{
if (getFK(i) >= 2000) break;
i++;
}
//当总和大于2000的话,表明i是最大值+1,所以最大值为i-1;这样才不会超界
Console.WriteLine(i - 1);
练习题3 猴子摘桃问题
//关系式:f(1) = N, f(2) = f(1)/2-1; f(3) = f(2)/2-1; f(n-1) = f(n-2)/2-1 f(n) = f(n-1)/2-1; -->f(n-1) = (f(n)+1)*2 //所以: f(n) = (f(n+1)+1)*2 出口 f(10) = 1
static int getPeak(int days)
{
if(days == 10)
{
return 1;
}
return (getPeak(days + 1) + 1) * 2;
}
for(int i = 1; i <= 10; i++)
{
Console.WriteLine("第{0}天的桃子数为:{1}",i, getPeak(i));
}
注意:做递归题目的时候,第一步最重要的就是找规律把关系式找出来,后面找出递归的停止条件,这样写程序的时候就迎刃而解了。