10.30
图的遍历
1. 图的两种存储方式
A. 数组模拟邻接表存储(普通数组/动态数组实现)
B. 邻接矩阵
2. 图的两种遍历方式
A. 深度优先搜索(DFS)
B. 广度优先搜索(BFS)
技巧:关键是处理父子关系。对于DFS来说,父亲出栈,其所有合法孩子入栈;对于BFS来说,父亲出队,其所有合法孩子入队。
重要的工作:判断孩子的合法性(不要重复并且满足约束条件)
3.代码
A.DFS
#include <bits/stdc++.h>
using namespace std;
#define MAXN 100
int n;//节点的数量
int m;//边的数量
struct edge
{
int to;//边的终点
int w;//边的权值
};
vector<edge> linker[MAXN];//有多少个节点就有多少个动态数组,第i个动态数组中存它的所有邻居节点。本质上v数组是一个二维数组(每一行可以不等长)
void insertEdge(int from, int to, int w)
{
linker[from].push_back({to, w});
}
bool vis[MAXN];
void dfs(int u)//u为父亲
{
cout<<u<<endl;
vis[u]=true;//标记父亲已访问
for(int i=0; i<linker[u].size(); i++)//枚举u的所有孩子
{
int v=linker[u][i].to;//v为u的第i个孩子
if(vis[v]==0)//判合法性(重复性),如果v没有被访问过,就访问它的子孙后代
{
dfs(v);//访问v及其子孙后代
}
}
}
int main()
{
cin>>n>>m;
for(int i=0; i<m; i++)
{
int x, y, z;
cin>>x>>y>>z;
insertEdge(x, y, z);
insertEdge(y, x, z);//变成无向图
}
dfs(0);
return 0;
}
/*
最基本的存储方式
4
5
0 3 1
1 0 1
1 2 1
2 0 1
2 1 1
*/
B.BFS
#include <bits/stdc++.h>
using namespace std;
#define MAXN 100
int n;//节点的数量
int m;//边的数量
struct edge
{
int to;//边的终点
int w;//边的权值
};
vector<edge> linker[MAXN];//有多少个节点就有多少个动态数组,第i个动态数组中存它的所有邻居节点。本质上v数组是一个二维数组(每一行可以不等长)
void insertEdge(int from, int to, int w)
{
linker[from].push_back({to, w});
}
bool vis[MAXN];
queue<int> q;
void bfs(int start)//start是根节点
{
//根节点需要单独处理
q.push(start);//根节点入队
vis[start]=true;//标记根节点
while(q.empty()==false)//队列不为空
{
int u=q.front();//取队首父亲
q.pop();//父亲出队
cout<<u<<endl;//输出父亲
for(int i=0; i<linker[u].size(); i++)//枚举u的所有孩子
{
int v=linker[u][i].to;//u的第i个孩子
if(vis[v]==0)//合法孩子入队(判重)
{
vis[v]=true;
q.push(v);
}
}
}
}
int main()
{
cin>>n>>m;
for(int i=0; i<m; i++)
{
int x, y, z;
cin>>x>>y>>z;
insertEdge(x, y, z);
insertEdge(y, x, z);//变成无向图
}
bfs(0);//从0号点开始广度
return 0;
}
/*
最基本的存储方式
4
5
0 3 1
1 0 1
1 2 1
2 0 1
2 1 1
*/