递归与回溯的理解

递归思想

以下部分文字图片转自文章一眼看懂递归
递归是什么?
在这里插入图片描述

求解问题 f(6), 由于 f(6) = n * f(5), 所以 f(6) 需要拆解成 f(5) 子问题进行求解,同理 f(5) = n * f(4) ,也需要进一步拆分,… ,直到 f(1), 这是「递」,f(1) 解决了,由于 f(2) = 2 f(1) = 2 也解决了,… f(n)到最后也解决了,这是「归」
所以递归的本质是能把问题拆分成具有相同解决思路的子问题,。。。直到最后被拆解的子问题再也不能拆分,解决了最小粒度可求解的子问题后,在「归」的过程中自然顺其自然地解决了最开始的问题

什么时候用递归?
1.一个问题可以分解成具有相同解决思路的子问题,子子问题,换句话说这些问题都能调用同一个函数
2.经过层层分解的子问题最后一定是有一个不能再分解的固定值的(即终止条件),如果没有的话,就无穷无尽地分解子问题了,问题显然是无解的
满足以上两个条件即可用递归解决问题

怎么用递归?(四步法)
1.明确函数的功能
2.找出递推公式和临界条件(出口)
3.将递推公式表达出来写到函数里
4.推导时间复杂度,看看会不会超时==,超时就得换

回溯是啥?
就是返回去做上一层未做完的事情,因为函数变量的存活期只在当前函数,所以变量的值为上一个函数的值,return是一层一层的去回溯的

递归样例(后续有经典题)
(1)这里说一下斐波那契数列的结论:每月大土对数等于上两个月的大兔对数之和,即an=an-1+an-2
得知了这个递归公式,我们就可以写出递归函数
代码实现如下

#include<stdio.h>

int Fibonacci (int n)
{
	if(n==0) return 0;
	else if(n==1) return 1;		
	else 
		return Fibonacci(n-1)+Fibonacci(n-2);
} 

int main()
{
	int n;
	while(~scanf("%d",&n)) 
		printf("%d\n\n",Fibonacci (n));
}

(2)我们可以用递归实现累加
代码实现如下,若输入3,此函数输出3+2+1=6

int recursion(int n)
{
	if(n==1) 		return 1;
	return n+recursion(n-1);
 } 

int main()
{
	int n,ans;
	scanf("%d",&n);
	printf("%d",recursion(n););
 } 

回溯样例
无回溯的递归如下,此函数输出 1 2 3 4 5

void a(int x)
{
	if(x>5) return;							//结束条件 
	printf("%d\n",x);
	a(x+1);									//递归语句 
}
int main()
{
	a(1);
	return 0;
 } 

(4)有回溯的递归,return语句每次返回一层,执行剩下的语句
代码实现如下,此函数输出1 2 3 4 5 然后开始回溯 5 4 3 2 1

void a(int x)
{
	if(x>5) return;					//结束条件 
	printf("%d\n",x);
	a(x+1);//递归语句
	printf("%d\n",x);				//回溯要执行的语句 (还债) 
}
int main()
{
	a(1);
	return 0;
 } 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值