图的遍历——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)队列存储的顶点都是它们本身已经访问过的但它们的邻接点未被访问过。
图的遍历——DFS和BFS模板(一般的图)的更多相关文章
- 图的遍历(DFS、BFS)
理论: 深度优先搜索(Depth_Fisrst Search)遍历类似于树的先根遍历,是树的先根遍历的推广: 广度优先搜索(Breadth_First Search) 遍历类似于树的按层次遍历的过程: ...
- 图的遍历DFS
图的遍历DFS 与树的深度优先遍历之间的联系 树的深度优先遍历分为:先根,后根 //树的先根遍历 void PreOrder(TreeNode *R){ if(R!=NULL){ visit(R); ...
- 图的遍历[DFS][BFS]
#include<iostream> #include<iostream> #include<cstring> #include<queue> #inc ...
- 图的遍历——DFS(矩形空间)
首先,这里的图不是指的我们一般所说的图结构,而是大小为M*N的矩形区域(也可以看成是一个矩阵).而关于矩形区域的遍历问题经常出现,如“寻找矩阵中的路径”.“找到矩形区域的某个特殊点”等等之类的题目,在 ...
- 图的遍历——DFS
原创 图的遍历有DFS和BFS两种,现选用DFS遍历图. 存储图用邻接矩阵,图有v个顶点,e条边,邻接矩阵就是一个VxV的矩阵: 若顶点1和顶点5之间有连线,则矩阵元素[1,5]置1,若是无向图[5, ...
- 图的遍历---DFS
类型一:邻接表 题目一:员工的重要性 题目描述 给定一个保存员工信息的数据结构,它包含了员工唯一的id,重要度 和 直系下属的id. 比如,员工1是员工2的领导,员工2是员工3的领导.他们相应的重要度 ...
- 图的遍历——DFS(邻接矩阵)
递归 + 标记 一个连通图只要DFS一次,即可打印所有的点. #include <iostream> #include <cstdio> #include <cstdli ...
- DFS和BFS模板
DFS: 该DFS框架以2D坐标范围为例,来体现DFS算法的实现思想 #include<cstdio> #include<cstring> #include<cstdli ...
- 16.boost图深度优先遍历DFS
#include <iostream> #include <boost/config.hpp> //图(矩阵实现) #include <boost/graph/adjac ...
随机推荐
- mysql,Jdbc工具类,只需一条sql实现简单查询
import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import ...
- Django框架(七)
15 Django组件-中间件 中间件 中间件的概念 中间件顾名思义,是介于request与response处理之间的一道处理过程,相对比较轻量级,并且在全局上改变django的输入与输出.因为改变的 ...
- CUDA 例程
scalar add #include <thrust/host_vector.h> #include <thrust/device_vector.h> #include &l ...
- Linux c读取系统内存使用信息
系统的内存使用信息能够在虚拟文件系统/proc/meminfo中找到,如图 所以只要打开/proc/meminfo文件,然后从中读取信息就好了 #include <stdio.h>#inc ...
- 安装一个Linux
Linux--虚拟机的的安装: 首先需要一个可执行(VMware-workstation-full-14.1.2-8497320.exe)的文件和一个Linux(CentOS-7-x86_64-DVD ...
- mysql InnoDB index 主键采用聚簇索引,二级索引不采用聚簇索引
原文链接 我的归纳: (1)InnoDB的主键采用聚簇索引存储,使用的是B+Tree作为索引结构,但是叶子节点存储的是索引值和数据本身(注意和MyISAM的不同). (2)InnoDB的二级索引不使用 ...
- eureka 服务注册与发现
1.创建父工程来管理依赖包 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http:/ ...
- CSS 文字概念小记
1.水平居中: 更多的是指宽度的居中,margin: 0 auto; 2.垂直居中: 是指高度的居中 PS:这个两个慨念我老是搞混,今天记录一下,防止下次又忘了
- Oracle创建视图的一个问题
问题: 在用户user1中创建视图,查询内容包含user2下的表数据, 创建视图的时候提示“权限不足”.执行如下语句: --为USER1授权 GRANT CREATE ANY TABLE TO USE ...
- Python 精进版SVIP版通过队列实现一个生产者消费者模型
import time from multiprocessing import Process,Queue,JoinableQueue #生产者 def producer(q): for i in r ...