C++递归算法回溯思想

一、最简单的递归问题(调用函数后无其他代码、不涉及复杂的回溯思想)

递归算法

  1. 递归算法:就是一种函数直接或者间接地调用自身的算法。
  2. 递归算法包括两种情况:函数自己调用自己;两个函数之间互相调用。
    注:(1)有递归边界;(2)每一步执行动作一样;(3)每调用一次规模缩小;(4)结果通过一步步结果层层退出。

在这里插入图片描述

#include<iostream>
using namespace std;
int a=0;
void story();
int main(){
	story();
	return 0;
}
void story(){
	cout<<"小和尚";
	a++;
	if(a<3) story();
	else cout<<"故事讲完了";
}
//答案是:小和尚小和尚小和尚故事讲完了

二、递归函数中的return不是结束整个递归函数哦

在这里插入图片描述
1、递归中的return常用来作为递归终止的条件,但是对于返回数值的情况,要搞明白它是怎么返回的。

2、递归的方式就是自己调用自己,而在有返回值的函数中,上一层的函数还没执行完就调用下一层,因此,当达到递归终止条件时,首先return的是最底层调用的函数,return之后,继续执行上一层调用该函数之后的代码,此时我们看到的是上一层的情况,当上一层剩余的代码执行完之后,表示上一层的函数也结束,此时再返回上上一层,执行递归代码之后的代码,如此往复循环,直到返回到最上层,结束整个递归过程。

3、需要注意的是,上一层执行递归之后的代码的时候,会调用下一层返回的值,也可以理解为在执行上一层代码的时候会调用下一层的实现过程,直到下一层执行完返回一个数值,然后再加上上一层的数值,就构成了上一层return的东西,如此往复。

多说无用,来实战吧!
在这里插入图片描述

三、递归(涉及回溯)举例

学生的年龄问题(递归的执行过程)

 问题描述:有 5 个学生坐在一起,问第 5 个学生多少岁?他说比第 4 个学生大 2岁,问第 4 个学生岁数,他说比第 3 个学生大 2 岁,问第 3 个学生,又说比第 2个学生大 2 岁,问第 2 个学生,说比第 1 个学生大 2 岁,最后问第 1 个学生,他说是 10 岁,请问第 5 个学生多大。
先来个代码

#include<iostream>
using namespace std;
//函数的定义,int值函数的返回值类型为int数据
int age(int n){
	int c;
	if(n==1){
		c = 10;
	}else{
		c = age(n-1) + 2;
	}
	//必须要用rteurn,因为第8行需要用到它的返回值
 	return c;
}
int main(){
	cout<<age(5);
	return 0;
}
//答案是:18

n本身的值没有变(只是把n-1作为实际参数传进去了),但是它作为实际参数传进来age函数里之后n其实变了

递归:c其实就相当于age(n),因为递归函数的返回值是return c;

n=5 c=age(4)+2
n=4 c=age(3)+2
n=3 c=age(2)+2
n=2 c=age(1)+2
n=1 c=10

回溯
n=1时age(1)=10
n=2时age(2)=12
n=3时age(3)=14
n=4时age(4)=16
n=5时age(5)=18

四、涉及较复杂的回溯思想

楼梯问题

1、问题描述:小明上楼梯,一步可以迈 1 个台阶、2 个台阶或者 3 个台阶,现共有 n(1≤n≤30)个台阶,请编程计算他所有可能的走法。
输入样例:4
输出样例:
1 1 1 1
1 1 2
1 2 1
1 3
2 1 1
2 2
3 1

#include<iostream>
using namespace std;
int a[1000];//定义这一步走多少台阶
int index;//定义第几步
void output(){
	for(int i=0;i<index;i++){
		cout<<a[i]<<" ";
	}
	cout<<endl;
}
//定义step函数
void step(int n){
	//设置结束的条件,表示可以形成一种走法
	if(n==0){
		output();
		return;
	}
	a[index++]=1;
	step(n-1);
	index--;
	if(n>1){
		a[index++]=2;
		step(n-2);
		index--;
	}
	if(n>2){
		a[index++]=3;
		step(n-3);
		index--;
	}
}
int main(){
	int n;//n表示总台阶数
	cin>>n;
	step(n);//step函数返回n阶台阶的总走法
	return 0;
}

递归:
n=4 a[0]=1 index=1
n=3 a[1]=1 index=2
n=2 a[2]=1 index=3
n=1 a[3]=1 index=4
n=0 output()函数输出1 1 1 1,return之后结束回到上一次递归、且此时
n=1 index=3 不符合两个if语句,又回到上一层递归
n=2 index=2 符合第一个if(n>1),则a(2)=2,index=3 ,n=0,则output()函数输出1 1 2
return之后回到上一次递归,也就是n=2,index=2,不符合if(n>2)回到上一次递归也就是n=3,index=1
符合if(n>1) 则a(1)=2,index=2,step(1),a(2)=1,index=3,step(0),调用output函数输出1 2 1

以此类推~~就不全部举例啦
在这里插入图片描述
其实吧,这个题要是不用编程思想解决的话

可以很简单

比如,用数学思维、找规律哈哈哈
n=1时只有1种走法
n=2时只有2种走法
n=3时只有4种走法
n=1时只有7种走法
变形版斐波那契数列哈哈
f(n)=f(n-1)+f(n-2)+f(n-3)

一句代码完美解决
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

是彦歆呀嘻嘻哈哈

你的鼓励将是我的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值