【C++ dfs return】dfs可以不写return吗?

目录

1、理解C++语言递归函数*

2、例题:leetcode 判断二分图(dfs)

 3. dfs不能不写return的情况

1.非法访问

2.无限递归


答案是:有可以不写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

猜你喜欢

转载自blog.csdn.net/icecreamTong/article/details/128101698
dfs