图的遍历——DFS和BFS模板(一般的图)

关于图的遍历,通常有深度优先搜索(DFS)和广度优先搜索(BFS),本文结合一般的图结构(邻接矩阵和邻接表),给出两种遍历算法的模板

1.深度优先搜索(DFS)

#include<iostream>
#include<unordered_map>
#include<queue>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<sstream>
#include<set>
#include<map>
using namespace std;
#define VERTEX_SIZE 100 //定义图中顶点数目

bool visited[VERTEX_SIZE];//建立顶点标记数组,用于判断顶点是否已经走过
class Graph{
.... //自定义图结构(邻接矩阵或者邻接表)
};

void DFSTraverse(Graph G)
{
    memset(visited,false,sizeof(visited));//初始化顶点标记数组
    for(int i = 0 ; i < VERTEX_SIZE;i++) //遍历图中的每个连通分量
        if(!visited[i])
            DFS(G,i);
}
void DFS(Graph G,int v)
{
    visited[v] = true;//修改标记
    visit(v);//访问顶点v
    for(int w = FirstAdjVex(G,v); w >= 0;w = NextAdjVex(G,v,w))//寻找顶点v的邻接点
        if(!visited[w])
            DFS(G,w);
}
void visit(int v)
{
   //自定义操作
   ;
}

int main()
{
    ...
}

关于这个模板,有几点需要注意的:

(1)此处的模板适用于以邻接表表示的图结构或者以邻接矩阵表示的图结构,若以邻接表表示的话,时间复杂度为O(n+e);若以邻接矩阵表示的话,时间复杂度为O(n^2)。其中n为图中节点的个数,e为边的个数。

(2)遍历图的限制条件比较少,只要是未访问过(visited[v] == false)就可以进行访问。

(3)寻找顶点v的邻接点那部分代码是伪代码,需要根据图的具体表示结构进行寻找(邻接矩阵找到相应行进行遍历;邻接表遍历相应的单链表)

(4)在函数DFSTraverse()中,加入了个for循环,目的是:如果图是非连通图的话,需要遍历每个连通分支。由此,可以利用DFS来判断图的连通性,如果从某个节点开始遍历(任意节点),能遍历到所有节点的话,俺么这个图就是连通的。相当于在上述模板中把DFSTraverse()函数中的for循环换成单次遍历。(参考《王道》P191)

2.广度优先搜索(BFS)

#include<iostream>
#include<unordered_map>
#include<queue>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<sstream>
#include<set>
#include<map>
using namespace std;
#define VERTEX_SIZE 100 //定义图中顶点数目

bool visited[VERTEX_SIZE];//建立顶点标记数组,用于判断顶点是否已经走过
class Graph{
....//自定义图结构(邻接矩阵或者邻接表)
};

void BFSTraverse(Graph G)
{
    memset(visited,false,sizeof(visited));//初始化顶点标记数组
    queue<int> Q;
    for(int i = 0 ; i < VERTEX_SIZE;i++)
        if(!visited[i])
            BFS(G,i,Q);
}
void BFS(Graph G,int v,queue<int> &Q)
{
    visited[v] = true;
    visit(v);//访问顶点v
    Q.push(v);//v入队
    while(!Q.empty())
    {
        int u = Q.front();
        Q.pop();
        for(int w = FirstAdjVex(G,u); w >= 0;w = NextAdjVex(G,u,w))//找到顶点w的所有邻接点
            if(!visited[w])//访问w的邻接点,并且访问过后将邻接点入队
            {
                visited[w] = true;
                visit(w);
                Q.push(w);
            }
    }
}
void visit(int v)
{
   //自定义操作
   ;
}

int main()
{
    ...
}

(1)BFS的时间复杂度与DFS是一样的。

(2)BFSTraverse()函数中的for循环和DFSTraverse()中的作用是一样的,都是遍历所有的连通分支,只不过遍历的顺序不同;所以同样可以用BFS来判断图的连通性。

(3)队列存储的顶点都是它们本身已经访问过的但它们的邻接点未被访问过。

原文地址:https://www.cnblogs.com/wangkundentisy/p/9284886.html

时间: 2024-10-15 11:57:39

图的遍历——DFS和BFS模板(一般的图)的相关文章

图的遍历 DFS和BFS

深度优先搜索 (Depth First Search, DFS): void DFS ( Vertex V ) { visited[ V ] = true; for ( V 点 的每个邻接点 W ) if ( !visited[ W ] ) DFS( W ); } 若有N 个顶点.E 条边,时间复杂度是 用邻接表存储图,有O(N+E) 用邻接矩阵存储图,有O(N 2 ) 广度优先搜索 (Breadth First Search, BFS) void BFS ( Vertex V ) { visi

图的遍历(DFS、BFS)

理论: 深度优先搜索(Depth_Fisrst Search)遍历类似于树的先根遍历,是树的先根遍历的推广: 广度优先搜索(Breadth_First Search) 遍历类似于树的按层次遍历的过程: java实现 Vertex.java package 图; public class Vertex{ String value; boolean isVisited; Vertex(String value) { this.value=value; this.isVisited=false; }

785. 判断二分图——本质上就是图的遍历 dfs或者bfs

785. 判断二分图 给定一个无向图graph,当这个图为二分图时返回true. 如果我们能将一个图的节点集合分割成两个独立的子集A和B,并使图中的每一条边的两个节点一个来自A集合,一个来自B集合,我们就将这个图称为二分图. graph将会以邻接表方式给出,graph[i]表示图中与节点i相连的所有节点.每个节点都是一个在0到graph.length-1之间的整数.这图中没有自环和平行边: graph[i] 中不存在i,并且graph[i]中没有重复的值. 示例 1: 输入: [[1,3], [

数据结构(15):图 深度优先遍历(DFS)

/*-----------------------------------------------*/ /* 邻接矩阵的DFS */ // 基于 数据结构(14) 中的邻接矩阵的结构 #include <iostream> using namespace std; typedef char VertexType; typedef int EdgeType; const int MAXVEX = 100; const int INFINITY = 65535; typedef struct {

树的遍历与图的遍历

研发时候,不要受原来的术语的影响,其实就是想着原来学过的或者看过的可以解决新遇到的问题,这其实是侥幸心理,忘记原来的术语吧,那只是你创新的源泉. 遍历就是把节点按一定规则构成一个线性序列,不同的规则得到不同顺序的线性序列,仅此而已 . 算法是实际问题工作步骤的抽象,不要一味想算法,想想实际情况怎么做的,然后提取算法,然后优化. 不论怎样,要和具体的数据结构结合在一起. 一.树的遍历 对于树的遍历,有三种,就拿前序遍历来说,得到的序列不论怎么拆分(子串,就是要连续),始 终要是根左右,跟在左右前面

图的遍历之深度优先搜索和广度优先搜索

转自:http://www.cnblogs.com/skywang12345/ 深度优先搜索的图文介绍 1. 深度优先搜索介绍 图的深度优先搜索(Depth First Search),和树的先序遍历比较类似. 它的思想:假设初始状态是图中所有顶点均未被访问,则从某个顶点v出发,首先访问该顶点,然后依次从它的各个未被访问的邻接点出发深度优先搜索遍历图,直至图中所有和v有路径相通的顶点都被访问到. 若此时尚有其他顶点未被访问到,则另选一个未被访问的顶点作起始点,重复上述过程,直至图中所有顶点都被访

图的遍历 (dfs与bfs)x

遍历是很多图论算法的基础,所谓图的遍历( graph traversal),也称为搜索( search),就是从图中某个顶点出发,沿着一些边访遍图中所有的顶点,且使每个顶点仅被访问一次.         遍历可以采取两种方法进行:         深度优先搜索( DFS: depth first search):         广度优先搜索( BFS: breadth first search). 对图进行存储与遍历: 输入: 第一行:顶点数n. 第二行:边数m. 以下m行,每行两个顶点编号u

图的两种遍历-DFS&amp;BFS

DFS和BFS在图中的应用: 图连通性判定:路径的存在性:图中是否存在环:求图的最小生成树:求图的关键路径:求图的拓扑排序. DFS:简单的说,先一直往深处走,直到不能再深了,再从另一条路开始往深处走,直到所有路都走完: struct node { int next; //E[i].next指向图中与i同父的下一个结点 int to; //E[i].to指向图中i的子结点 }E[110]; int N; int fa[110]; //记录各点的父结点 bool vis[110]; //记录这个点

算法导论--图的遍历(DFS与BFS)

转载请注明出处:勿在浮沙筑高台http://blog.csdn.net/luoshixian099/article/details/51897538 图的遍历就是从图中的某个顶点出发,按某种方法对图中的所有顶点访问且仅访问一次.为了保证图中的顶点在遍历过程中仅访问一次,要为每一个顶点设置一个访问标志.通常有两种方法:深度优先搜索(DFS)和广度优先搜索(BFS).这两种算法对有向图与无向图均适用. 以下面无向图为例: 1.深度优先搜索(DFS) 基本步骤: 1.从图中某个顶点v0出发,首先访问v