采用深度优先搜索法(DFS)遍历图
伪码如下:
DFS(u){
vis[u] = true;//设置u已被访问
for(从u出发能到达的所有顶点v)//枚举从u出发可以到达的所有顶点v
if vis[v] == false //如果v未被访问
DFS(v); //递归访问v
}
DFSTrave(G){
for(G的所有顶点u)//对G的所有顶点u
if vis[u] == false //如果u未被访问
DFS(u); //访问u所在的连通块
}
1,邻接矩阵实现:
const int maxv = 1000;
const int INF = 1000000000;
int n,G[maxnv][maxv];
bool vis[maxv] ={false};
void DFS(int u,int depth){
vis[u] = true;//设置u已被访问
for(int v = 0;v < n;v++){
if(vis[v] == false&&G[u][v] != INF){
DFS(v,depth + 1);
}
}
}
void DFSTrave(){ //遍历图G
for(int u = 0;u < n;u++){ //对每个顶点u
if(vis[u] == false){ //如果u未被访问
DFS(u, 1); //访问u和u所在的连通块,1表示初始为第一层
}
}
}
2,邻接表实现:
vector<int> Adj[maxv]; //图G为邻接表
int n; //n为顶点个数,maxv为最大顶点个数
bool vis[maxv] = {false};
void DFS(int u,int depth){
vis[u] = true; //设置u为已被访问
for(int i = 0;i < Adj[u].size();i++){//对从u出发可以到达的所有顶点v
int v = Adj[u][i];
if(vis[v] == false){ //如果v未被访问
DFS(v,depth + 1); //访问v,深度加1
}
}
}
void DFSTrave(){//遍历图G
for(int u = 0;u < n;u++){//对每个顶点u
if(vis[u] == false){//如果u未被访问
DFS(u,1); //访问u和u所在的连通块,1表示初始为第一层
}
}
}
采用广度优先搜索法遍历(BFS)图
伪代码如下:
BFS(u){
queue q;//定义队列q
inq[u] = true;
while(q非空){
取出q的队首元素u进行访问;
for(从u出发可达的所有顶点v){
if(inq[v] == false) {
将v入队;
inq[v] = true;
}
}
}
}
BFSTrave(G){//遍历图G
for(G的所有顶点u){//枚举G的所有顶点u
if(inq[u] == false){//如果u未曾加入过队列
BFS(u);// 遍历u所在的连通块
}
}
}
1,邻接矩阵的实现如下:
int n,G[maxv][maxv];
bool inq[maxv][maxv];
void BFS(int u){
queue<int > q;
q.push(u);
inq[u] = true;
while(!q.empty()){
int u = q.front();
q.pop();
for(int v = 0;v < n;v++){
//如果u的邻接点v未曾加入过队列
if(inq[v] == false&&G[u][v] != INF){
q.push(v);
inq[v] = true;
}
}
}
}
void BFSTrave(){//遍历图G
for(int u = 0;u < n;u++){//枚举所有顶点
if(inq[u] == false){//如果u未曾加入过队列
BFS(q); //遍历u所在的连通块
}
}
}
2,邻接表的实现如下:
vector<int> Ad[maxv];
int n;
bool inq[maxv] = {false};
void BFS(int u){
queue<int > q;
q.push(u);
inq[u] = true;
while(!q.empty()){
int u = q.front();
q.pop(); //将队首元素出队
for(int i = 0;i < Adj[u].size;i++){//枚举从u出发能到达的所有顶点
int v = Adj[u][i];
if(inq[v] == false){
q.push(v);//将v入队
inq[v] = true; //标记v为已被加入过队列
}
}
}
}
void BFSTrave(){
for(int u = 0;u< n;u++){//枚举所有顶点
if(inq[u] == false){
BFS(q); //遍历u所在的连通块
}
}
}
当需要输出连通块内所有其他的顶点的层号时,需要定义结构体来存放层号,具体实现如下:
struct Node{
int v; //顶点编号
int layer;//顶点层号
};
vector<Node> Adj[N];
void BFS(int s){
queue<Node>q;//BFS队列
Node start; //起始顶点
start.v = s; //起始顶点编号
start.layer = 0; //起始顶点层号为0
q.push(start); //将起始顶点入队
inq[start.v] = true;//起始顶点的编号设为已被加入过队列
while(!q.empty()){
Node topNode = q.front(); //取出队首顶点
q.pop(); //队首顶点出队
int u = topNode.v; //队首顶点的编号
for(int i = 0;i < Adj[u].size(); i++){
Node next = Adj[u][i];
next.layer = topNode.layer + 1;
//如果next的编号未加入过队列
if(inq[next.v] == false){
q.push(next); //将next入队
inq[next.v] = true;//next的编号设为已被加入过队列
}
}
}
}