广度优先遍历(BFS)与深度优先遍历(DFS)

一、广度优先遍历(图的广度优先遍历类似于二叉树的层序遍历)

1、概念


(1)邻接矩阵

  • 先从一个点出发,将其所有的邻接点放到一个对列中
  • 当放完之后
  • 从队头的点开始,找是否有邻接点,如果有的话,再从队尾接上
  • 如果没有就队列头部元素出队,然后找新的对列元素时候有邻接点,如果有的话,再从队尾接上
  • 之后的过程一样
  • 但按照这样的方式找完之后,如果图中还有没有被访问的点的话,就从未访问的点开始进行同样的过程

(2)邻接表

在邻接表中,如果已经给出了一个邻接表,那么在遍历的时候,就有一定的顺序,在邻接表中,谁在前面,谁还没有遍历,则先遍历谁,先将谁放到对列中。


2、框架

#include <bits/stdc++.h>

using namespace std;

const int maxn=100;
bool visit[maxn][maxn];//访问标记//是否被访问
int dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}};//方向向量
//如果向左运动的话,x+1,y+0,所以第一个代表向左运动
//如果向右运动的话,x-1,y+0,所以第二个代表向左运动
//如果向上运动的话,x+0,y+1,所以第三个代表向上运动
//如果向下运动的话,x+0,y-1,所以第四个代表向下运动

struct State//BFS对列中数据状态
{
    int x,y;//坐标位置
    int Strp_Counter;//搜索步数统计器
};
State a[maxn];

bool CheckState(State s)
{
    if(!visit[s.x][s.y]&&...)//满足约束条件
        return 1;
    else
        return 0;
}

void bfs(State st)
{
    queue<State> q;//BFS对列
    State now,next;//定义两个状态,当前和下一个
    st.Strp_Counter=0;//计数器清0
    q.push(st);
    visit[st.x][st.y]=1;//访问标记
    while(!q.empty())
    {
        now=q.front();
        if(now==G)//出现目标态,此时为Step_Counter 的最小值,可以退出即可
        {
            ......//做相关处理
            return;
        }
        for(int i=0;i<4;i++)
        {
            next.x=now.x+dir[i][0]; // 按照规则生成下一个状态
            next.y=now.y+dir[i][1];
            next.Strp_Counter=now.Strp_Counter+1;//计数器加1
            if(CheckState(next))
            {
                q.push(next);
                visit[next.x][next.y]=1;
            }
        }
        q.pop();//队首元素出队
    }
    return;
}


int main()
{
    ......
    return 0;
}

二、深度优先遍历(图的深度优先遍历类似于二叉树的先序遍历)

 

1、概念


(1)邻接矩阵

  • 访问图中的某一个顶点v
  • 从v的未被访问的邻接点出发到点v1,访问v1的邻接点,如果v1有未被访问的邻接点,那么就继续访问这个未被访问的邻接点,否则回退到上一个点,一直回退到某一个含有未被访问的邻接的点为止,然后继续进行遍历,如果按照这个方法遍历完之后
  • 若此时图中尚有顶点未被访问,则从一个未被访问的顶点出发,重新进行深度优先遍历,直到图中所有顶点均被访问过为止。
     

2、框架

#include <bits/stdc++.h>

using namespace std;

const int maxn=100;
bool visit[maxn][maxn];//访问标记//是否被访问
int dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}};//方向向量
//如果向左运动的话,x+1,y+0,所以第一个代表向左运动
//如果向右运动的话,x-1,y+0,所以第二个代表向左运动
//如果向上运动的话,x+0,y+1,所以第三个代表向上运动
//如果向下运动的话,x+0,y-1,所以第四个代表向下运动
int maps[maxn][maxn];//坐标范围



bool CheckEdge(int x,int y)//边界和约束条件的判断
{
    if(!visit[x][y]&&...)//约束条件
        return 1;
    else
        return 0;
}

void dfs(int x,int y)
{
    visit[x][y]=1;//标记该节点被访问过
    if(maps[x][y]==G)// 出现目标态G
    {
        ......//做相应处理
        return;
    }
    for(int i=0;i<4;i++)
    {
        if(CheckEdge(x+dir[i][0],y+dir[i][1]))//按照规则生成下一个节点
        dfs(x+dir[i][0],y+dir[i][1]);
    }
    return;//没有下层搜索节点,回溯
}


int main()
{
    ......
    return 0;
}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值