数据结构-图的搜索学习

数据结构学习

学习参考:https://www.jianshu.com/p/70952b51f0c8

图的搜索一般有两种方式,一种是广度优先BFS,另一种是深度优先DFS

广度优先搜索在进一步遍历图中顶点之前,先访问当前顶点的所有邻接结点。

深度优先搜索在搜索过程中访问某个顶点后,需要递归地访问此顶点的所有未访问过的相邻顶点。

假设图的邻接矩阵如下

int Graph[5][5] = {
    { 0, 1, 1, 0, 0 },
    { 0, 0, 1, 1, 0 },
    { 0, 1, 1, 1, 0 },
    { 1, 0, 0, 0, 0 },
    { 0, 0, 1, 1, 0 }
};

BFS

#include <bits/stdc++.h>
#define fi first
#define se second
#define pb push_back
#define fio ios::sync_with_stdio(false);cin.tie(0);
#define pii pair<int,int>
#define vi vector<int>
#define vc vector<char>
#define fr front
#define mii map<int,int>
#define si(a) scanf("%d",&a)
#define sl(a) scanf("%I64d",&a);
#define slf(a) scanf("%lf",&a);
#define pi acos(-1)

const int INF=0x3f3f3f3f;
const int N=2e5+5;

typedef long long ll;
typedef double db;
typedef unsigned long long ull;
using namespace std;

int Graph[5][5] = {         //也可以用vector的邻接表实现
    { 0, 1, 1, 0, 0 },
    { 0, 0, 1, 1, 0 },
    { 0, 1, 1, 1, 0 },
    { 1, 0, 0, 0, 0 },
    { 0, 0, 1, 1, 0 }
};

int vis[N];
void BFS(int start)
{
    queue<int> q;
    q.push(start);
    while(!q.empty())
    {
        int fr=q.fr;
        cout<<q.fr<<" ";
        q.pop();//出队
        for (int i=1;i<=5;i++)//5是边界
        {
            if(!vis[i]&&Graph[fr-1][i-1])//如果自己没有被访问过并且上一个被访问到了
            {
                vis[i]=1;//打上标记
                q.push(i);//入队
            }
        }
    }
    /*
    以这张图为例
    搜索1的可达点并打上标记,1出队2、3入队
    搜索2的可达点并打上标记,2出队4入队
    搜索3的可达点并打上标记,3出队
    搜索4的可达点并打上标记,4出队,无入队
    此时队列已空,结束,遍历一遍就知道哪个点不可达了
    */
}


int main()
{
    fio;
memset(vis,0,sizeof(vis));
for (int i=1;i<=5;i++) { if(vis[i]) continue; else BFS(i); } }

 

DFS

DFS这里需要有回溯的思想,包括八皇后问题等等都是很典型的题目。

访问一个点后递归这个点所有的邻接点,直到没有邻接点为止,向上回溯

 

#include <bits/stdc++.h>
#define fi first
#define se second
#define pb push_back
#define fio ios::sync_with_stdio(false);cin.tie(0);
#define pii pair<int,int>
#define vi vector<int>
#define vc vector<char>
#define fr front
#define mii map<int,int>
#define si(a) scanf("%d",&a)
#define sl(a) scanf("%I64d",&a);
#define slf(a) scanf("%lf",&a);
#define pi acos(-1)

const int INF=0x3f3f3f3f;
const int N=2e5+5;

typedef long long ll;
typedef double db;
typedef unsigned long long ull;
using namespace std;

int Graph[5][5] = {         //也可以用vector的邻接表实现
    { 0, 1, 1, 0, 0 },
    { 0, 0, 1, 1, 0 },
    { 0, 1, 1, 1, 0 },
    { 1, 0, 0, 0, 0 },
    { 0, 0, 1, 1, 0 }
};

int vis[N];
void DFS(int start)
{
    vis[start]=1;
    for (int i=1;i<=5;i++)
    {
        if(!vis[i]&&Graph[start-1][i-1]==1)
            DFS(i);
    }
    cout<<start<<" ";
}


int main()
{
    fio;
    for (int i=1;i<=5;i++)
    {
        if(vis[i]) continue;
        else DFS(i);
    }
}

经过看了一些博客之后,感觉说懂都懂,但是用起来就很不顺手,该去做题了2333

DFS还有非递归的做法,在后面我会慢慢学习,先掌握最基础的再说

----------------------------------------------------------------------------------------------------------------------------------------

更新一波,贴一份dfs的模板

 1 bool vis[N];
 2 int n;
 3 
 4 void dfs(int x)
 5 {
 6     if()//判断是否越界
 7     if()//判断是否满足条件,如果满足,ans++并且return
 8     {
 9         ans++;
10         return;
11     }
12     for (int i=1;i<=n;i++)
13     {
14         if()//判断是否满足继续下去的条件
15         {
16             vis[i]=1;//满足的话打标记
17             dfs(x+1);//继续dfs
18             vis[i]=0;//回溯
19         }
20     }
21     dfs(x+1);//继续dfs
22 }

 

转载于:https://www.cnblogs.com/TheSilverMoon/p/9341621.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值