蒟蒻说算法——递归

蒟蒻说算法——递归

想要表情包吗?我可以给你,请看下面。
emmmm…:
在这里插入图片描述
呵呵~
今天不发题解,让我们来谈谈算法。这此提到的算法是非常的常见,这一次的算法就是——递归

递归的原理

想要了解递归,就必须要了解一下递归的工作原理,才能成功的使用。递归的本质就是递归函数调用自身。可以粗略的理解为无限制造for嵌套,是不是很简单 😃?然后我们要知道递归是把调用的递归函数全部丢到一个栈里面,再一个一个去处理。so easy~

递归函数的框架

框架并不难,跟函数很像,看一下下面的代码框架:

#include<bits/stdc++.h>
using namespace std;
void/*函数类型,就是int,bool,void之类的*/ fill/*函数名*/(/*需要的参数*/){
	if(/*返回条件或超出界限*/){
		return ;//如果是void不用return其他的,其他都要 
	}
	/*其它乌七八糟的代码,中间一定要出现调用自身函数,不然就不是递归啦*/
} 
int main(){
	fill(/*乌七八糟的参数*/);
	return 0; 
}

其它的自己编码,就是开头的if绝对不能漏哦,漏了的话,呵呵呵~ 你可以试试,肯定会一直调用调用再调用,只要你不return的话。

使用递归的题目

使用递归的题目也是非常的多,来一道比较经典的题目:斐波那契数列,题目大家应该都知道,在这里就不细说题目了。
直接看一下代码:

#include<bits/stdc++.h>
using namespace std;
int f(int num){
	if(num == 1||num == 2){//返回的地方
		return 1;
	}else{
		return f(num-1)+f(num-2);//前两项之和
	}
}
int main(){
	int n;
	cin>>n;
	cout<<f(n);
} 

挺精简的吧,简单的作者都没什么注释可写的了。只要你试试,40左右就爆炸了(超时)
你只要输出一下每次调用的是数列中的第几项,就会得到一下结果(n = 7)的时候是这样的:
在这里插入图片描述
显而易见,第五项被重复了两遍,第四项被重复了3遍,是不是很惊喜?如果数据大一点,再大一点的话,就会重复计算很多遍,导致大量时间浪费,所以超时不是事。所以优化就是必须的了。

递归优化

递归的优化作者知道一种,叫做记忆化搜索,用人话来说就是每次要计算时就先找一下在结果数组中有没有,有的话直接使用,没有的话先算出结果,存到结果数据里面,方便下一次调用。只不过有一个要注意的东西就是使用是要先尽量的减少参数,不然的话你就有可能使用三维数组甚至四维。再说了,参数那么多,也不容易命中,是吧。给大家看一下优化后的代码:

#include<bits/stdc++.h>
using namespace std;
int result[100]; 
int f(int num){
	if(num == 1||num == 2){//返回的地方
		return 1;
	}else{
		if(result[num]!=0){
			return result[num];
		}else{
			cout<<"f("<<num<<")"<<endl; 
			result[num] =  f(num-1)+f(num-2);
		}
		return result[num];//前两项之和
	}
}
int main(){
	int n;
	cin>>n;
	cout<<f(n);
} 

运行结果是这样的:
在这里插入图片描述
是吧?这样就快很多了吧?用文件输入的话n = 40都只要0.5632s就OK了,上面那个作者中间10输错了,耗掉了时间,总体来说是快了很多了。

递归就讲完了,不会太难吧。
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值