目录
答案是:有可以不写return的情况。
1、理解C++语言递归函数*
c++的递归不一定需要显式地写return。隐式return的情况是:如果执行到函数的结尾,就会自动返回到上一级。
#include <iostream>
using namespace std;
void up_and_down(int n)
{
cout << "level: " << n << endl;/*1*/
if (n < 4)
up_and_down(n + 1);
cout << "level: " << n << endl;/*2*/
}
int main()
{
up_and_down(1);
return 0;
}
/*输出:
level: 1
level: 2
level: 3
level: 4
level: 4(在这里,函数执行完了/*2*/,执行完毕自动返回上一级)
level: 3(返回上一级后,执行n=3的up_and_down(int n) 的/*2*/,执行完毕又自动返回上一级)
level: 2
level: 1
*/
2、例题:leetcode 判断二分图(dfs)
class Solution {
private:
static constexpr int UNCOLORED = 0;
static constexpr int RED = 1;
static constexpr int GREEN = 2;
vector<int> color;
bool valid;
public:
void dfs(int node, int c, const vector<vector<int>>& graph) {
color[node] = c;
int cNei = (c == RED ? GREEN : RED);
for (int neighbor: graph[node]) {
if (color[neighbor] == UNCOLORED) {
dfs(neighbor, cNei, graph);
if (!valid) {
return;
}
}
else if (color[neighbor] != cNei) {
valid = false;
return;
}
}
}
bool isBipartite(vector<vector<int>>& graph) {
int n = graph.size();
valid = true;
color.assign(n, UNCOLORED);
for (int i = 0; i < n && valid; ++i) {
if (color[i] == UNCOLORED) {
dfs(i, RED, graph);
}
}
return valid;
}
};
其中在dfs函数里出现了两个return:
一个是 ,表示在这个点之后的深度优先的过程中,有没有出现过非法的情况(在此题中一条边的两个点染了同样颜色为非法),如果是非法的(!valid),就在这层函数return, 返回到上一级的函数中。
然后因为valid是全局变量,所以一旦valid=false,就会一直一直return,直到退出第一层的dfs并回到主程序isBipartite(),执行dfs的下一条。
另一个是,表示在这个点有没有出现非法的情况,如果有,就在这层函数return。
此外,还有一种隐式的return,就是一条边中的两个点,node已着色,另一个点neighbor和node同色,即(color[neighbor] != UNCOLORED) &&(color[neighbor] == cNei), 代码里没写出来,而这种情况是合法的,如果neighbor是这种情况,那么代码应该什么也不干,继续执行,一直遍历node的所有neighbor,如果都是合法的,那么这个node及其深度优先的子节点就是合法的。至此,程序执行完这层的所有代码,就会隐式地返回到这个node的上一层函数中。
3. dfs不能不写return的情况
1.非法访问
举例来说:比如用深度优先搜索遍历一棵树,如果到了叶子节的nullptr左右子节点,如果不返回,就会继续试图dfs 两个空指针的数据,但是空指针是不指向任何一个数据的,这不就出问题了吗,编译器就会报错:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
void dfs(vector<int>&res,TreeNode* root){
if(root==nullptr)
return;
dfs(res, root->left);
dfs(res,root->right);
res.push_back(root->val);
}
vector<int> postorderTraversal(TreeNode* root) {
//dfs
vector<int> res;
dfs(res, root);
return res;
}
};
2.无限递归
又比如说,不return会无限递归的情况:
此处例子参考:(47条消息) dfs中return回溯问题_唐火的博客-CSDN博客_dfs中的return
这段不写return 没关系,不会无限递归
#include <iostream>
using namespace std;
int n, k;
const int N = 1010;
int a[N];
bool st[N];
void dfs(int u) {
if (u == k + 1) {
for (int i = 1; i <= k; i++) {
cout << a[i] << " ";
}
cout << endl;
return ;
}
for (int i = 1; i <= n; i++) {
if (!st[i]) {
st[i] = true;
a[u] = i;
dfs(u + 1);
st[i] = false;
}
}
}
int main() {
cin >> n >> k;
dfs(1);
return 0;
}
这段不写会无限递归:
#include <iostream>
using namespace std;
int n, k;
const int N = 1010;
int a[N];
bool st[N];
void dfs(int u) {
if (u > k + 1) {
for (int i = 1; i <= k; i++) {
cout << a[i] << " ";
}
cout << endl;
return ;
}
for (int i = 1; i <= n; i++) {
if (!st[i]) {
st[i] = true;
a[u] = i;
dfs(u + 1);
st[i] = false;
}
}
}
int main() {
cin >> n >> k;
dfs(1);
return 0;
}
3.等你来补充~~
博主刚开始接触编程不久,发现的例子就这两种。 小伙伴们你们有什么不能不写return的例子,快留言告诉博主吧~给你比耶( •̀ ω •́ )y