情景构建:
将一个三位数倒序输出。
一、解:
#include<bits/stdc++.h>
using namespace std;
void Dxs1(int n){
cout<<n;
}
void Dxs2(int n){
cout<<n%10;
Dxs1(n/10);
}
void Dxs3(int n){
cout<<n%10;
Dxs2(n/10);
}
int main(){
Dxs3(123);
return 0;
}
二、合并:
#include<bits/stdc++.h>
using namespace std;
void Dxs(int n){
if(n==1){
cout<<n;
}else{
cout<<n%10;
Dxs(n/10);
}
}
int main(){
Dxs(123);
return 0;
}
疑惑:函数没执行完,再次调用能行吗?
解答:去啃函数调用过程,栈帧。
说人话:函数就像公式,参数就像数据。
做人事:脑子不够纸条来凑。
三、优化:
#include<bits/stdc++.h>
using namespace std;
void Dxs(int n){
cout<<n%10;
if(n>10)Dxs(n/10);
}
int main(){
Dxs(123);
return 0;
}
思路:输出个位,n降权。
“递”:Dxs(n/10)——逐步去掉个位的过程。
四、更懵逼或者有通达:
#include<bits/stdc++.h>
using namespace std;
void Dxs(int n){
if(n>10)Dxs(n/10);
cout<<n%10;
}
int main(){
Dxs(123);
return 0;
}
问题:在“递”之后输出,输出结果是什么?
五、设计递归函数还得先按部就班,没有正确代码,你是想优化BUG吗?
0、相同操作是什么?会退化为不用调用递归函数吗?不满足这两者,就不要递归了,没有相同操作还用调用自身吗?没有边界你要递到哪?无限循环了好不好。
1、形参是什么,返回值要不要有?——做什么——函数入口(也是整个递归的入口)
2、何时退出?——做到什么程度——函数出口(也是整个递归的出口)
3、何时调用自身?——怎么做——函数调用
六、闲聊
1、递归函数和非递归函数调用起来没区别。也就是说,递归占用栈空间,默认栈空间有1024*1024byte,太深的递归就崩了,而且进出栈也会消耗时间。
2、递归都可以转化为循环或用stack(栈)结构实现。但是,在解决复杂问题时,使用递归或栈可以更容易的把精力集中在子问题的求解上。例如可以很方便的使用增量式或表式记录进行剪枝,即提高效率又避免崩掉。
3、递归、stack实现的都是深度优先遍历。