图的遍历(DFS和BFS)
声明:图片及内容基于https://www.bilibili.com/video/BV1rp4y1Q72r?from=articleDetail
图的遍历




深度优先遍历(DFS)
DFS核心是递归和栈
原理


邻接矩阵DFS代码
template <class T>
void MGraph<T>::DFS(int i){
cout<<vertex[i]<<" ";
visit[i]=1;
for(int j=0;j<vertexNum;j++){ //对邻接矩阵的第i行的每一列遍历
if(visit[j]==0&&arc[i][j]!=0&&arc[i][j]!=INFINIT){
DFS(j);
}
}
}
template <class T>
void MGraph<T>::DFSTraverse(){
for(int i=0;i<vertexNum;i++){ //visit数组初始化
visit[i]=0;
}
for(int i=0;i<vertexNum;i++){
if(!visit[i])
DFS(i);
}
}
完整代码
#include<iostream>
#define MAXVAX 100
using namespace std;
const int INFINIT=65535;
int visit[MAXVAX];
template <class T>
class MGraph {
private:
T *vertex; //顶点信息
int **arc; //邻接矩阵
int vertexNum,arcNum; //顶点数,边数
public:
MGraph(T v[],int n,int e);
~MGraph();
void DFS(int i);
void DFSTraverse();
void display();
};
template <class T>
void MGraph<T>::DFS(int i){
cout<<vertex[i]<<" ";
visit[i]=1;
for(int j=0;j<vertexNum;j++){
if(visit[j]==0&&arc[i][j]!=0&&arc[i][j]!=INFINIT){
DFS(j);
}
}
} template <class T>
void MGraph<T>::DFSTraverse(){
for(int i=0;i<vertexNum;i++){
visit[i]=0;
}
for(int i=0;i<vertexNum;i++){
if(!visit[i])
DFS(i);
}
}
template <class T>
MGraph<T>::MGraph(T v[],int n,int e) { //n是顶点数,e是边数
vertexNum=n;
arcNum=e;
vertex = new T[vertexNum]; //建立顶点信息
arc = new int*[vertexNum]; //建立邻接表
for(int i=0; i<vertexNum; i++)
arc[i]=new int[vertexNum]; for(int i=0; i<vertexNum; i++) { //初始化顶点信息
vertex[i]=v[i];
}
for(int i=0;i<vertexNum;i++) //初始化邻接表
for(int j=0;j<vertexNum;j++){
if(i==j) arc[i][j]=0;
else arc[i][j]=INFINIT;
} int vi,vj,w;
for(int i=0;i<arcNum;i++){
cout<<"请输入边的两个顶点和这条边的权值"<<endl;
cin>>vi>>vj>>w; //输入边依附的两个顶点的编号 和权值
arc[vi][vj]=w; //有边标志
}
} template <class T>
void MGraph<T>::display(){
for(int i=0;i<vertexNum;i++){
for(int j=0;j<vertexNum;j++){
cout<<arc[i][j]<<"\t";
}
cout<<endl;
}
cout<<endl; for(int i=0;i<vertexNum;i++){
cout<<vertex[i]<<" ";
}
cout<<endl;
} template <class T>
MGraph<T>::~MGraph(){
delete []vertex;
for(int i=0;i<vertexNum;i++)
delete [] arc[i];
delete [] arc;
}
int main(){
const char* v[5]={"v0","v1","v2","v3","v4"};
MGraph<const char*> mgraph(v,5,6);
mgraph.display();
mgraph.DFSTraverse();
return 0;
}
邻接表DFS代码
void ALGraph::DFS(int v){
visited[v]=1;
cout<<adjList[v].vertex<<" ";
ArcNode *p=adjList[v].firstEdge;
while(p){
if(!visited[p->adjvex])
DFS(p->adjvex);
p=p->next;
}
}
void ALGraph::DFSTraverse(){
int i;
for(i=0;i<vertexNum;i++){
visited[i]=0;
}
for(i=0;i<vertexNum;i++){
if(!visited[i]){
DFS(i);
}
}
}
完整代码
#include<iostream>
#include<string.h>
using namespace std;
const int MAX=10;
int visited[4]={0,0,0,0};
typedef struct ArcNode{ //边结点
int adjvex;
ArcNode *next;
}ArcNode;
typedef struct { //表头
int vertex;
ArcNode *firstEdge;
}VertexNode[MAX];
class ALGraph{
private:
int vertexNum;
int arcNum;
VertexNode adjList;
public:
ALGraph(int v[],int n,int e);
void display();
void DFS(int v);
void DFSTraverse();
};
void ALGraph::DFSTraverse(){
int i;
for(i=0;i<vertexNum;i++){
visited[i]=0;
}
for(i=0;i<vertexNum;i++){
if(!visited[i]){
DFS(i);
}
}
}
void ALGraph::DFS(int v){ visited[v]=1;
cout<<adjList[v].vertex<<" ";
ArcNode *p=adjList[v].firstEdge;
while(p){
if(!visited[p->adjvex])
DFS(p->adjvex);
p=p->next;
}
}
ALGraph::ALGraph(int v[],int n,int e){
vertexNum=n;
arcNum=e;
for(int i=0;i<vertexNum;i++){
adjList[i].vertex=v[i];
adjList[i].firstEdge=NULL;
}
int vi,vj;
ArcNode *s;
for(int i=0;i<arcNum;i++){
cout<<"请输入第"<<i+1<<"条边的两个顶点在数组中的坐标"<<endl;
cin>>vi>>vj;
s=new ArcNode;
s->adjvex=vj;
s->next=adjList[vi].firstEdge;
adjList[vi].firstEdge=s;
s=new ArcNode;
s->adjvex=vi;
s->next=adjList[vj].firstEdge;
adjList[vj].firstEdge=s;
}
}
void ALGraph::display(){
for(int i=0;i<vertexNum;i++){
ArcNode *p=adjList[i].firstEdge;
cout<<adjList[i].vertex;
if(p) cout<<"->";
while(p){
cout<<p->adjvex<<" ";
p=p->next;
if(p) cout<<"->";
}
cout<<endl;
}
}
int main(){
int v[4]={0,1,2,3};
ALGraph algraph(v,4,4);
algraph.display();
algraph.DFSTraverse();
return 0;
}
广度优先遍历(BFS)
BFS核心是队列
原理


邻接矩阵BFS代码
template <class T>
void MGraph<T>::BFS(int i) {
queue<int> q;
visit[i]=1;
q.push(i);
while(!q.empty()) {
int t=q.front();
cout<<vertex[t]<<" ";
q.pop();
for(int j=0; j<vertexNum; j++) {
if(!vertex[i]&&arc[i][j]!=0&&arc[i][j]!=INFINIT) {
visit[j]=1;
q.push(j);
}
}
}
}
template <class T>
void MGraph<T>::BFSTraverse() {
for(int i=0; i<vertexNum; i++) { //visit数组初始化
visit[i]=0;
}
for(int i=0; i<vertexNum; i++) { //BFS
if(!visit[i])
BFS(i);
}
}
完整代码
#include<iostream>
#include<queue>
#define MAXVAX 100
using namespace std;
const int INFINIT=65535;
int visit[MAXVAX];
template <class T>
class MGraph {
private:
T *vertex; //顶点信息
int **arc; //邻接矩阵
int vertexNum,arcNum; //顶点数,边数
public:
MGraph(T v[],int n,int e);
~MGraph();void display();
void BFS(int i);
void BFSTraverse();
}; template <class T>
void MGraph<T>::BFS(int i) {
queue<int> q;
visit[i]=1;
q.push(i);
while(!q.empty()) {
int t=q.front();
cout<<vertex[t]<<" ";
q.pop();
for(int j=0; j<vertexNum; j++) {
if(!vertex[i]&&arc[i][j]!=0&&arc[i][j]!=INFINIT) {
visit[j]=1;
q.push(j);
}
}
}
} template <class T>
void MGraph<T>::BFSTraverse() {
for(int i=0; i<vertexNum; i++) { //visit数组初始化
visit[i]=0;
}
for(int i=0; i<vertexNum; i++) {
if(!visit[i])
BFS(i);
}
}
template <class T>
MGraph<T>::MGraph(T v[],int n,int e) { //n是顶点数,e是边数
vertexNum=n;
arcNum=e;
vertex = new T[vertexNum]; //建立顶点信息
arc = new int*[vertexNum]; //建立邻接表
for(int i=0; i<vertexNum; i++)
arc[i]=new int[vertexNum]; for(int i=0; i<vertexNum; i++) { //初始化顶点信息
vertex[i]=v[i];
}
for(int i=0; i<vertexNum; i++) //初始化邻接表
for(int j=0; j<vertexNum; j++) {
if(i==j) arc[i][j]=0;
else arc[i][j]=INFINIT;
} int vi,vj,w;
for(int i=0; i<arcNum; i++) {
cout<<"请输入边的两个顶点和这条边的权值"<<endl;
cin>>vi>>vj>>w; //输入边依附的两个顶点的编号 和权值
arc[vi][vj]=w; //有边标志
}
} template <class T>
void MGraph<T>::display() {
for(int i=0; i<vertexNum; i++) {
for(int j=0; j<vertexNum; j++) {
cout<<arc[i][j]<<"\t";
}
cout<<endl;
}
cout<<endl; for(int i=0; i<vertexNum; i++) {
cout<<vertex[i]<<" ";
}
cout<<endl;
} template <class T>
MGraph<T>::~MGraph() {
delete []vertex;
for(int i=0; i<vertexNum; i++)
delete [] arc[i];
delete [] arc;
}
int main() {
const char* v[5]= {"v0","v1","v2","v3","v4"};
MGraph<const char*> mgraph(v,5,6);
mgraph.display();
mgraph.BFSTraverse();
return 0;
}
邻接表BFS代码
void ALGraph::BFS(int i){
queue<int> q;
visited[i]=1;
q.push(i);
while(!q.empty()){
int t=q.front();
cout<<adjList[t].vertex<<" ";
q.pop();
ArcNode *p=adjList[i].firstEdge;
while(p){
if(!visited[p->adjvex]){
q.push(p->adjvex);
visited[p->adjvex]=1;
}
p=p->next;
}
}
}
void ALGraph::BFSTraverse(){
int i;
for(i=0;i<vertexNum;i++){
visited[i]=0;
}
for(i=0;i<vertexNum;i++){
if(!visited[i]){
BFS(i);
}
}
}
完整代码
#include<iostream>
#include<string.h>
#include<queue>
using namespace std;
const int MAX=10;
int visited[4]={0,0,0,0};
typedef struct ArcNode{ //边结点
int adjvex;
ArcNode *next;
}ArcNode;
typedef struct { //表头
int vertex;
ArcNode *firstEdge;
}VertexNode[MAX];
class ALGraph{
private:
int vertexNum;
int arcNum;
VertexNode adjList;
public:
ALGraph(int v[],int n,int e);
void display();void BFS(int v);
void BFSTraverse();
};
void ALGraph::BFS(int i){
queue<int> q;
visited[i]=1;
q.push(i); while(!q.empty()){
int t=q.front();
cout<<adjList[t].vertex<<" ";
q.pop();
ArcNode *p=adjList[i].firstEdge;
while(p){
if(!visited[p->adjvex]){
q.push(p->adjvex);
visited[p->adjvex]=1;
}
p=p->next;
}
}
}
void ALGraph::BFSTraverse(){
int i;
for(i=0;i<vertexNum;i++){
visited[i]=0;
}
for(i=0;i<vertexNum;i++){
if(!visited[i]){
BFS(i);
}
}
} ALGraph::ALGraph(int v[],int n,int e){
vertexNum=n;
arcNum=e;
for(int i=0;i<vertexNum;i++){
adjList[i].vertex=v[i];
adjList[i].firstEdge=NULL;
}
int vi,vj;
ArcNode *s;
for(int i=0;i<arcNum;i++){
cout<<"请输入第"<<i+1<<"条边的两个顶点在数组中的坐标"<<endl;
cin>>vi>>vj;
s=new ArcNode;
s->adjvex=vj;
s->next=adjList[vi].firstEdge;
adjList[vi].firstEdge=s;
s=new ArcNode;
s->adjvex=vi;
s->next=adjList[vj].firstEdge;
adjList[vj].firstEdge=s;
}
}
void ALGraph::display(){
for(int i=0;i<vertexNum;i++){
ArcNode *p=adjList[i].firstEdge;
cout<<adjList[i].vertex;
if(p) cout<<"->";
while(p){
cout<<p->adjvex<<" ";
p=p->next;
if(p) cout<<"->";
}
cout<<endl;
}
}
int main(){
int v[4]={0,1,2,3};
ALGraph algraph(v,4,4);
algraph.display();
algraph.BFSTraverse();
return 0;
}
图的遍历(DFS和BFS)的更多相关文章
- 图的遍历——DFS和BFS模板(一般的图)
关于图的遍历,通常有深度优先搜索(DFS)和广度优先搜索(BFS),本文结合一般的图结构(邻接矩阵和邻接表),给出两种遍历算法的模板 1.深度优先搜索(DFS) #include<iostrea ...
- 图的遍历(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
原创 图的遍历有DFS和BFS两种,现选用DFS遍历图. 存储图用邻接矩阵,图有v个顶点,e条边,邻接矩阵就是一个VxV的矩阵: 若顶点1和顶点5之间有连线,则矩阵元素[1,5]置1,若是无向图[5, ...
- 图的遍历——DFS(矩形空间)
首先,这里的图不是指的我们一般所说的图结构,而是大小为M*N的矩形区域(也可以看成是一个矩阵).而关于矩形区域的遍历问题经常出现,如“寻找矩阵中的路径”.“找到矩形区域的某个特殊点”等等之类的题目,在 ...
- 图的遍历---DFS
类型一:邻接表 题目一:员工的重要性 题目描述 给定一个保存员工信息的数据结构,它包含了员工唯一的id,重要度 和 直系下属的id. 比如,员工1是员工2的领导,员工2是员工3的领导.他们相应的重要度 ...
- 图的遍历——DFS(邻接矩阵)
递归 + 标记 一个连通图只要DFS一次,即可打印所有的点. #include <iostream> #include <cstdio> #include <cstdli ...
- 16.boost图深度优先遍历DFS
#include <iostream> #include <boost/config.hpp> //图(矩阵实现) #include <boost/graph/adjac ...
- 图的数据结构的实现与遍历(DFS,BFS)
//图的存储结构:const int MAXSIZE = 10;//邻接矩阵template<class T>class MGraph {public: MGraph(T a[], ...
随机推荐
- C++中数字与字符串之间的转换(转载自http://www.cnblogs.com/luxiaoxun/)
C++中数字与字符串之间的转换 1.字符串数字之间的转换(1)string --> char * string str("OK"); char * p = str ...
- 华企盾DSC远程桌面、实时监控连接不上常见处理方法
1.检测策略是否勾选了远程桌面需要客户端确认或者勾选了客户端显示"允许远程维护"选项 2.检查客户端5097目录是否有MgrDll.dll.uvnserver.exe文件(是否被杀 ...
- cs上线Linux
cs上线Linux 下载和配置crossC2 首先到项目地址:https://github.com/gloxec/CrossC2/releases下载两个文件 后缀为.cna的为cs的插件文件,启动c ...
- 构建健康游戏环境:DFA算法在敏感词过滤的应用
现在的游戏有敏感词检测这一点,相信大家也不陌生了,不管是聊天,起名,签名还是简介,只要是能让玩家手动输入的地方,一定少不了敏感词识别,至于识别之后是拒绝修改还是星号替换,这个就各有各的做法了,但是绕不 ...
- 0X01 位运算笔记
位运算,经常可以用来处理一些数学或动归方面的问题,通常会在数据范围较小的情况下使用. 为方便起见,一个 \(\mathrm{n}\) 位二进制数从右到左分别为第 \(\mathrm{0 \sim n ...
- Java 并发编程(三)锁与 AQS
本文 JDK 对应的版本为 JDK 13 由于传统的 synchronized 关键字提供的内置锁存在的一些缺点,自 JDK 1.5 开始提供了 Lock 接口来提供内置锁不具备的功能.显式锁的出现不 ...
- 浅析华为云基于HBase MTTR上的优化实践
摘要:主要介绍华为云在HBase 2.x内核所做的一些MTTR优化实践. 本文分享自华为云社区<华为云在HBase MTTR上的优化实践>,作者: 搬砖小能手. 随着HBase在华为云的广 ...
- 一文总结GaussDB通信原理知识
摘要:从发展历程到通信模型设计,到你了解一下GaussDB通信原理知识. MPPDB通信库发展历程 Postgres-XC 方法:采用libpq通信库实现CN和DN之间的连接,CN负责计算,DN仅进行 ...
- 云计算的三种模式IaaS/PaaS/SaaS/BaaS对比:SaaS架构设计分析
SaaS--软件即服务(Software as a Service)的出现改变了传统使用软件转变为使用服务. SaaS与传统软件的最大区别是,前者按年付费租用服务,后者一次买断.这貌似只是" ...
- centos8 测地卸载php5.6 与卸载php7
centos8 yum php 默认安装 php7.1.2 我想卸载php7 ,安装php5.6 yum remove php 无法彻底卸载干净.必须强制删除,使用下面命令查看全部php软件包 rpm ...