关于图的遍历,通常有深度优先搜索(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)队列存储的顶点都是它们本身已经访问过的但它们的邻接点未被访问过。

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

  1. 图的遍历(DFS、BFS)

    理论: 深度优先搜索(Depth_Fisrst Search)遍历类似于树的先根遍历,是树的先根遍历的推广: 广度优先搜索(Breadth_First Search) 遍历类似于树的按层次遍历的过程: ...

  2. 图的遍历DFS

    图的遍历DFS 与树的深度优先遍历之间的联系 树的深度优先遍历分为:先根,后根 //树的先根遍历 void PreOrder(TreeNode *R){ if(R!=NULL){ visit(R); ...

  3. 图的遍历[DFS][BFS]

    #include<iostream> #include<iostream> #include<cstring> #include<queue> #inc ...

  4. 图的遍历——DFS(矩形空间)

    首先,这里的图不是指的我们一般所说的图结构,而是大小为M*N的矩形区域(也可以看成是一个矩阵).而关于矩形区域的遍历问题经常出现,如“寻找矩阵中的路径”.“找到矩形区域的某个特殊点”等等之类的题目,在 ...

  5. 图的遍历——DFS

    原创 图的遍历有DFS和BFS两种,现选用DFS遍历图. 存储图用邻接矩阵,图有v个顶点,e条边,邻接矩阵就是一个VxV的矩阵: 若顶点1和顶点5之间有连线,则矩阵元素[1,5]置1,若是无向图[5, ...

  6. 图的遍历---DFS

    类型一:邻接表 题目一:员工的重要性 题目描述 给定一个保存员工信息的数据结构,它包含了员工唯一的id,重要度 和 直系下属的id. 比如,员工1是员工2的领导,员工2是员工3的领导.他们相应的重要度 ...

  7. 图的遍历——DFS(邻接矩阵)

    递归 + 标记 一个连通图只要DFS一次,即可打印所有的点. #include <iostream> #include <cstdio> #include <cstdli ...

  8. DFS和BFS模板

    DFS: 该DFS框架以2D坐标范围为例,来体现DFS算法的实现思想 #include<cstdio> #include<cstring> #include<cstdli ...

  9. 16.boost图深度优先遍历DFS

    #include <iostream> #include <boost/config.hpp> //图(矩阵实现) #include <boost/graph/adjac ...

随机推荐

  1. laravel数据库迁移 和 路由防攻击

    命令:php  artisan  migrate 防攻击:

  2. laravel StartSession中间件的实现原理

    1. 打开app\Http\Kernel.php,找到StartSession的位置.这里要说一下,middleware中的中间件是都会被执行的,但执行的顺序我不知道,还需看源码来实现 protect ...

  3. java泛型的理解

    总体介绍泛型: 1.泛型是计算机程序中一种重要的思维方式,它将数据结构和算法与数据类型相分离,使得同一套数据结构和算法,能够应用于各种数据类型,而且还可以保证类型安全,提高可读性.在Java中,泛型广 ...

  4. 牛客网第4场A

    链接:https://www.nowcoder.com/acm/contest/142/A 来源:牛客网 题目描述 A ternary , , or . Chiaki has a ternary in ...

  5. Android设备终端监控可能用到的工具

    先记录工具,以后详细分析 add-property-tagcheck-lost+foundcpueatercpustatsdaemonizedexdumpdirectiotestfiokexecloa ...

  6. Python3解析dex文件

    一.说明 1.1 背景说明 看<加密与解密>的时候反复听说“PE文件格式”,到Android安全兴起就不断听说“dex文件格式”.意思是看得懂的,但自己不能手解析一番总觉得不踏实,所以决定 ...

  7. vue教程自学笔记(二)

    三.模板语法 1.文本 数据绑定最常见的形式就是使用“Mustache”语法 (双大括号) 的文本插值. 通过v-once指令,你也能执行一次性地插值,当数据改变时,插值处的内容不会更新. 2.原始H ...

  8. PB测款方法 店铺运费模板 设置

    https://www.wishhack.com/article/44.html 子账号有权限设置运费

  9. SSH Struts2+hiberante+Spring整合

    使用SSH框架编写学生信息: 一.新建Java工程: (1)建立好Java各层级之间的结构:业务处理层dao,数据模型层domain,页面请求处理层(Struts2 MVC层)action,servi ...

  10. js计算时间差

    <!doctype html> <html lang="en"> <head> <meta http-equiv="Conten ...