cppDFS和BFS

11 篇文章 0 订阅

DFS核心代码:

关于dfs参数问题,什么在变化,就把什么设置成参数

  • 如果要求输出所有可能的解,往往都是要用深度优先搜索。
  • 如果是要求找出最优的解,或者解的数量,往往可以使用动态规划。
void dfs()//参数用来表示状态  

    if(到达终点状态)  

    {  

        ...//根据题意添加  

        return;  

    }  

    if(越界或者是不合法状态)  

        return;  

    if(特殊状态)//剪枝

        return ;

    for(扩展方式)  

    {  

        if(扩展方式所达到状态合法)  

        {  

            修改全局变量;//根据题意来添加  

            visit标记;  

            dfs();

            恢复全局变量//回溯部分

            (还原标记)//是否还原标记根据题意

            //如果加上(还原标记)就是 回溯法 

        }  
 }

全排列问题

先给一个正整数 ( 1 < = n < = 10 )

例如n=3,所有组合,并且按字典序输出:

1 2 3

1 3 2

2 1 3

2 3 1

3 1 2

3 2 1

#include<iostream>

#include<cmath>

using namespace std;

 

void combineDfs(int dep, vector<int> &cur, vector<vector<int>> &res, int len, int vis[]){

    if(dep == len + 1)//到达终点状态

    {

        res.push_back(cur);

        return ;

    }

    

    for(int i = 1; i <= len; ++i){

        if(vis[i] == false)//扩展方式所达到状态合法(结点可访问

        //if(vis[i]==false&& i>cur[dep])剪枝后一个进入的要比当前的大

        {

            vis[i] = true;

            cur.push_back(i);//当前层数用某个,若层数返回记得退回

            combineDfs(dep+1, cur, res, len, vis);

            //一趟深搜结束,还原标记下次还可用来深搜

            cur.pop_back();

            vis[i] = false;//结点是否可重复使用

        }

    }

        

}

                                                                      

int main(){

    int vis[10] = {0};

    int n;

    n = 3;

    vector<int> cur;

    vector<vector<int>> res1;

    combineDfs(1, cur, res1, n, vis);



    return 0;

}

回文字符串问题

类似全排列,亦是for 1:len展开所有

bool isPalindrome(string s){

    return s == string(s.rbegin(), s.rend());

}


void palindromeDfs(string s, vector<string> &cur, vector<vector<string>> &res){

    if(s == ""){

        res.push_back(cur);

        return ;

    }

    

    //展开方式,每次从0开始取i个单位当子串

    for (int i = 1; i <= s.size(); ++i) {

        string sub = s.substr(0, i);

        if (isPalindrome(sub)) {

            cur.push_back(sub);

            //当前是回文,从i开始再取len-i个子串

            palindromeDfs(s.substr(i, s.size() - i), cur, res);

            cur.pop_back();

        }

    }

}

vector<vector<string>> partition(string s){

    vector<vector<string>> res;

    vector<string> cur;

    palindromeDfs(s, cur, res);

    return res;

}

BFS:

这里写图片描述

最典型的模版就是树的层序遍历:

void levelOrder(TreeNode* root){
    if(root == NULL) return;
    queue<TreeNode*> que;//初始化队列Q
  
    TreeNode* cur = NULL;
  
    que.push(root);//Q=起点
  
    while (!que.empty()) {
        cur = que.front();//取队首元素出队
        que.pop();
      
        cout << cur->val << " ";
      
        if(cur->left) que.push(cur->left);//满足目标状态
        if(cur->right) que.push(cur->right);
    }
    return;
}

矩阵中的路径问题:

int h[606][606];
const int mm = pow(10,9);
class point {
public:
    int x, y;
    point(int a, int b) :x(a), y(b){}
};

int maina()
{
    int n, m;
    cin >> n >> m;
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < m; ++j) {
            cin >> h[i][j];
        }
    }
    int x, y, z, w;
    cin >> x >> y >> z >> w;
  
    queue<point> q;
    q.push(point(x, y));
    int count = 0;
  
    while (!q.empty()) {
        point cur = q.front();
        q.pop();
        if (cur.x == z && cur.y == w) {
            ++count;
            count %= mm;
        }
        if (cur.x - 1 >= 0 && h[cur.x - 1][cur.y] > h[cur.x][cur.y])
            q.push(point(cur.x - 1, cur.y));
        if (cur.x + 1 < n && h[cur.x + 1][cur.y] > h[cur.x][cur.y])
            q.push(point(cur.x + 1, cur.y));
        if (cur.y - 1 >= 0 && h[cur.x][cur.y - 1] > h[cur.x][cur.y])
            q.push(point(cur.x, cur.y - 1));
        if (cur.y + 1 < m && h[cur.x][cur.y + 1] > h[cur.x][cur.y])
            q.push(point(cur.x, cur.y + 1));
    }
    cout << count << endl;
    
    return 0;
}

BFS和DFS对比

  • DFS多用于连通性问题因为其运行思想与人脑的思维很相似,故解决连通性问题更自然。
  • BFS多用于解决最短路问题,其运行过程中需要储存每一层的信息,所以其运行时需要储存的信息量较大,如果人脑也可储存大量信息的话,理论上人脑也可运行BFS。

多数情况运行BFS所需的内存会大于DFS需要的内存(DFS一次访问一条路,BFS一次访问多条路)。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值