学习札记:递归

递归,recursion,所谓“大道至简”,递归是一种自身调用自身的算法。

优点:简单,爽!
缺点:有点耗费算力。

当某个操作,它的定义属于“自身的嵌套”,这时一般用递归都能解决问题。比如:斐波那切数列,Fib(n)=Fib(n-1)+Fib(n-2),属于自身调用。
再比如:阶乘,n!=n*(n-1)!

因此,这两个功能都可以用递归来实现。

斐波那切数列一般用来解决兔子问题:

假定一对大兔子每月能生一对小兔子,且每对新生的小兔子经过一个月可以长成一对大兔子,具备繁殖能力,如果不发生死亡,且每次均生下一雌一雄,问一年后共有多少对兔子?

让我们列出来兔子的增长:
月份:1 2 3 4 5 6 7 8 9 10
对数:1 1 2 3 5 8 13 21 34 55

兔子对数明显以斐波那契数列的规律增长。因此,假使要算x个月后兔子的总对数,实际上就是对fibonacci数列的前x项求和。

代码如下:

int rabbit(int month) {
	if (month == 1 || month == 2) { return 1; }
	else return rabbit(month - 1) + rabbit(month - 2);
}
int main() {
	int sum = 2;
	for (int i = 3; i <= 12; i++) {
		sum += rabbit(i);
	}
	cout << sum;
}

函数rabbit需要一个月份参数,即上文的x。在x=1或x=2时,Fib(1)与Fib(2)就是1.因此,此时输出1即可。而在x>2时,fib(x)=fib(x-1)+fib(x-2),此时直接输出这一式即可。
比如,x=5时,输出的是第三项与第四项的和。
第三项就是x=3时rabbit的返回值,即第一项与第二项的和,为2.
第四项就是x=4时rabbit的返回值,即第二项与第三项的和,第二项为1,第三项再次递归,启动!值为2.
故,rabbit(5)=2+1+2=1+1+1+2=5.

由此可以看出,递归十分简洁,也易于理解。但递归次数一多起来,对同一函数的调用就会很多,造成程序效率低下。

《阶乘如何处理?》

int pong(int x) {
	if (x == 1)return 1;
	if (x > 1)return pong(x - 1)*x;
}

输入x,比如x=5,此时5>1,那么返回pong(4)×5,此时x=4,pong(4)的值实际为pong(3)×4,如此往复,pong(3)=pong(2)×3,pong(2)=pong(1)×2,pong(1)0=1,就得到了:pong(5)=5×4×3×2×1=120.

不难发现,递归的一大特点是:递归总有一个尽头。在斐波那契列里,是Fib(1)与Fib(2),在阶乘里是1!。如果没有这个尽头,递归将无穷无尽地调用函数自身,程序爆炸。

实际上,任何自身由自身定义的操作,都存在着递归算法供人们使用。它虽然不是最出彩的那个,甚至有点笨拙,但它一定是能够走到尽头的伙伴。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值