图的遍历(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[], ...
随机推荐
- python生成列表的时间复杂度
在刷题的时候,经常碰到需要生成非常大的邻接矩阵,往往我们都是用 list 存储,但是我在最近刷题的过程中就遇上了TLE的情况,原因就是生成邻接矩阵时间太花时间了. 先说结论:[ ]* n 比 [ fo ...
- Codeforces #475 div2
题目链接:http://codeforces.com/contest/964 A题 答案n/2+1: B题 讨论三种情况 c>b c==b c<b C题 数论,逆元+快速幂,但是我一直卡在 ...
- ElasticSearch之cat plugins API
命令样例如下: curl -X GET "https://localhost:9200/_cat/plugins?v=true&pretty" --cacert $ES_H ...
- java漏洞学习平台搭建
java漏洞平台搭建 项目地址 : https://github.com/j3ers3/Hello-Java-Sec 配置mvn 先配置一下mvn,下载后解压 proxychains wget htt ...
- maven系列:聚合与继承
目录 一.聚合 创建Maven模块,设置打包类型为pom 设置当前聚合工程所包含的子模块名称 二. 继承 问题导入 创建Maven模块,设置打包类型为pom 在父工程的pom文件中配置依赖关系(子工程 ...
- 神经网络基础篇:梯度下降法(Gradient Descent)
梯度下降法 梯度下降法可以做什么? 在 测试集上,通过最小化代价函数(成本函数)\(J(w,b)\)来训练的参数\(w\)和\(b\), 如图,在第二行给出和之前一样的逻辑回归算法的代价函数(成本函数 ...
- 万万没想到,我在夜市地摊解决了MySQL临时表空间难题~~
都说"大隐隐于市,高手在深宫".突如其来的"摆地摊"风潮,让原本冷清的街道热闹非凡,也让众人发现了那些神龙见首不见尾的大神们. 这不,小毛在下班的途中就遇到了大 ...
- 视频编码耗时长、编码帧发送失败…DVPP视频编码问题典型案例分析
摘要:本期就分享几个关于DVPP视频编码问题的典型案例,并给出原因分析及解决方法 本文分享自华为云社区<DVPP媒体数据处理视频编码问题案例>,作者:昇腾CANN. DVPP(Digita ...
- MindSpore:不用摘口罩也知道你是谁
[本期推荐专题]从三大主流前端技术出发,看看它们各自特性,以及如何从业务特性出发,选择合适的框架. 摘要:我们基于MindSpore设计了一种人脸识别算法,以解决口罩遮挡场景下的人脸识别问题.该算法的 ...
- 华为云GaussDB(for Influx)揭密第六期:数据分级存储
摘要:GaussDB(for Influx)通过冷热数据存储分离,在提供海量数据高性能存储的同时可节省85%的存储成本,高效满足时序应用各种场景. 本文分享自华为云社区<华为云GaussDB(f ...