图的遍历
图的遍历分为两种
我只是蒟蒻一枚
所以就只会写一下基础的东西
- 以dfs为核心的深度优先遍历
void dfs(int cur)//cur表示当前节点的编号
{
cout<<cur<<" ";
sum++;//访问节点数++
if(sum==n) return ;//访问完 直接return
for(int i=1;i<=n;i++)
{
if(e[i][cur]==1&&vis[i]==0)//判断
{
vis[i]=1;//标记为已经访问
dfs(i);//继续以这个点为节点深度遍历
/*
注意 这里不需要回溯
因为整一个图只需要遍历一次
*/
}
}
return ;
} `
上面是深度优先遍历的核心代码
下面来解决main函数里的、
`
int main()
{
cin>>n>>m;
//这里采用的是邻接矩阵存图法
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
if(i==j) e[i][j]=0;
else e[i][j]=999999;
for(int i=1;i<=m;i++){
cin>>a>>b;
e[a][b]=e[b][a]=1;
//这里是无向图 如果是有向图就是e[a][b]=1 || e[b][a]=1
}
vis[1]=1;//一点要把根节点标记 因为我们dfs就是从根节点开始的
dfs(1);
}`
好的深度优先遍历就讲完了,下面我们来看一下以bfs为核心的广度优先遍历
- 广度优先遍历
直接上代码 注释在代码里面有
#include<bits/stdc++.h>
using namespace std;
int n,m,a,b,e[105][105],vis[1000],tail,head,que[10000];
//vis[i]用来检查是否用过
//e[i][j]检查从i到j是否有路
int main()
{
scanf("%d %d",&n,&m);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
if(i==j) e[i][j]=0;
else e[i][j]=9999999;
//邻接矩阵存储法 同一个点设为0 其余设为正无穷
for(int i=1;i<=m;i++){
cin>>a>>b;//输入有路的两个节点
e[a][b]=e[b][a]=1;
//因为是无向图
//所以有连接的两端都赋值为1
}
head=1,tail=1;
//队列初始化
que[tail]=1;//第一个节点入队(根节点)
tail++;//指向下一个
vis[1]=1;//标记根节点已经走过
//当队列不为空
while(tail>head&&tail<=n)
{
int cur=que[head];
//que[head]表示现在在访问的节点
//方便广度遍历 p134有图
for(int i=1;i<=n;i++)
{
if(e[cur][i]==1&&vis[i]==0)//满足条件
{
que[tail]=i;//入队
tail++;//指向下一个
vis[i]=1;//标记为访问过
}
if(tail>n) break;//当tail==n+1时 说明已经遍历完成
//因为尾指针永远指向下一个
}
head++;//出队(换下一个继续广度)
}
for(int i=1;i<tail;i++) cout<<que[i]<<" ";
//输出
return 0;
}