图的遍历(深度优先搜索)

article/2025/9/20 6:56:07

1、深度优先搜索遍历过程

图的深度优先搜索(Depth First Search),和树的先序遍历比较类似。

它的思想:假设初始状态是图中所有顶点均未被访问,则从某个顶点v出发,首先访问该顶点,然后依次从它的各个未被访问的邻接点出发深度优先搜索遍历图,直至图中所有和v有路径相通的顶点都被访问到。 若此时尚有其他顶点未被访问到,则另选一个未被访问的顶点作起始点,重复上述过程,直至图中所有顶点都被访问到为止。

显然,深度优先搜索是一个递归的过程

深度优先遍历特点是,选定一个出发点后进行遍历,能前进则前进,若不能前进,回退一步再前进,或再回退一步后继续前进。依此重复,直到所有与选定点相通的所有顶点都被遍历。

2、示例

对图7-25连通无向图采用深度优先搜索遍历可得到顶点访问序列:v0,v1,v3,v7,v4,v8,v2,v5,v6

对图7-26连通无向图采用深度优先搜索遍历可得到顶点访问序列:v0,v1,v3,v2,v4,v5,v6,v7


对图7-27连通无向图采用深度优先搜索遍历可得到顶点访问序列:v0,v1,v4,v3,v2或v2,v3,v0,v1,v4或v2,v1,v0,v4,v3


3、连通图的深度优先遍历

   给定一图G=<V,E>,用visited[i]表示顶点i的访问情况,初值设为0,表示所有顶点未被访问过,当顶点被访问过时置1。则初始情况下所有的visited[i]都为0。假设从顶点V0开始遍历,则下一个遍历的顶点是V0第一个邻接点Vi,接着遍历Vi第一个邻接点Vj,……直到所有的顶点都被访过。

4、代码

无向图,邻接矩阵存储:

对图7-25深度优先遍历:

#include <iostream>
using namespace std;
#define INFINITY  65535 /* 表示权值的无穷*/
typedef int EdgeType;//边上的权值类型
typedef int VertexType;//顶点类型
const int MaxSize=100;
int visited[MaxSize];//全局标识数组class MGraph//邻接矩阵类
{public:MGraph(){vertexNum=0;edgeNum=0;}MGraph(VertexType a[],int n);//构造函数,初始化具有n个顶点的零图void CreateMGraph1(MGraph *Gp);//建立无向图的邻接矩阵void DFS(int v);//从v出发深度优先遍历的递归函数void DFS1(int v);//从v出发深度优先遍历的非递归函数public:int vertexNum,edgeNum;//顶点数和边数EdgeType adj[MaxSize][MaxSize];//邻接矩阵VertexType vertex[MaxSize];//顶点表
};
//构造函数,初始化具有n个顶点的零图
MGraph::MGraph(VertexType a[],int n)
{vertexNum=n;edgeNum=0;for(int i=0;i<n;i++) vertex[i]=a[i];for(int i=0;i<n;i++)for(int j=0;j<n;j++)adj[i][j]=0;
}//建立无向图的邻接矩阵表示
void MGraph::CreateMGraph1(MGraph *Gp)
{int i, j, k;cout << "请输入顶点数和边数(空格分隔):" << endl;cin >> Gp->vertexNum >> Gp->edgeNum;cout << "请输入顶点信息(空格分隔):" << endl;for (i = 0; i < Gp->vertexNum; i++)cin >> Gp->vertex[i];for (i = 0; i < Gp->vertexNum; i++){for (j = 0; j < Gp->vertexNum; j++)Gp->adj[i][j] = 0;}for (k = 0; k < Gp->edgeNum; k++){cout << "请输入边(vi, vj)的上标i,下标j(空格分隔):" << endl;cin >> i >> j;Gp->adj[i][j] = 1;Gp->adj[j][i] = 1;// 因为是无向图,矩阵对称}
}//从v出发深度优先遍历的递归函数
void MGraph::DFS(int v)
{int n=vertexNum;//顶点数目if(v<0||v>=n) throw "位置出错";cout<<vertex[v]<<" ";//输出顶点vvisited[v]=1;//被访问过for(int j=0;j<n;j++)if(visited[j]==0&&adj[v][j]==1)//没被访问过且存在边(v,j)DFS(j);
}
//从v出发深度优先遍历的非递归函数
void MGraph::DFS1(int v)
{int S[MaxSize],n=vertexNum,top=-1,j;if(v<0||v>=n) throw "位置出错";cout<<vertex[v]<<" ";//输出顶点vvisited[v]=1;//被访问过S[++top]=v;//顶点v进栈while(top!=-1){v=S[top];//栈顶元素出栈for(j=0;j<n;j++){if(visited[j]==0&&adj[v][j]==1)//没被访问过且存在边(v,j){cout<<vertex[j]<<" ";visited[j]=1;S[++top]=j;break;}}if(j==n) top--;}
}
int main()
{MGraph grph;grph.CreateMGraph1(&grph);for(int i=0;i<MaxSize;i++)visited[i]=0;for(int i=0;i<grph.vertexNum;i++){for(int j=0;j<grph.vertexNum;j++){cout<<grph.adj[i][j]<<" ";}cout<<endl;}cout<<"递归深度优先遍历结果:"<<endl;grph.DFS(0);for(int i=0;i<MaxSize;i++)visited[i]=0;cout<<endl<<"非递归深度优先遍历结果:"<<endl;grph.DFS1(0);return 0;
}


无向图,邻接表存储:

图7-25:

#include <iostream>
using namespace std;
#define INFINITY  65535 /* 表示权值的无穷*/
typedef int EdgeType;//边上的权值类型
typedef int VertexType;//顶点类型
const int MaxSize=100;
int visited[MaxSize];//全局标识数组
//无向图邻接表。边表结点结构
struct EdgeNode
{int adjvex;//邻接点域EdgeNode *next;//指向下一个边结点的指针
};
//无向图邻接表。表头结点结构
struct VexNode
{VertexType vertex;//顶点EdgeNode *firstedge;//边表的头指针
};
//邻接表类
class ALGraph
{public:ALGraph()//无参构造函数{vertexNum=0;edgeNum=0;for(int i=0;i<MaxSize;i++)adjlist[i].firstedge=NULL;}ALGraph(VertexType a[],int n);//有参构造函数void createGraph(int start, int end);//创建图,采取前插法void DFSL(int v);//从v出发深度优先遍历可达顶点递归函数void DFSL1(int v);//从v出发深度优先遍历可达顶点的非递归函数void displayGraph(int nodeNum);//打印void CountComp(ALGraph g);//求连通分量数,判断图的连通性private:VexNode adjlist[MaxSize];//存放顶点表的数组int vertexNum,edgeNum;//图的顶点数和边数
};
//有参构造函数。构造顶点表
ALGraph::ALGraph(VertexType a[],int n)
{vertexNum=n;edgeNum=0;for(int i=0;i<vertexNum;i++){adjlist[i].vertex=a[i];adjlist[i].firstedge=NULL;}
}
//创建图,采取前插法
void ALGraph::createGraph(int start, int end)
{//边(start,end)//adjlist[start].vertex=start;//表头结点中的顶点EdgeNode *p=new EdgeNode;//边结点p->adjvex=end;//邻接点//p->weight=weight;p->next=adjlist[start].firstedge;//前插法插入边结点padjlist[start].firstedge=p;
}
//打印存储的图
void ALGraph::displayGraph(int nodeNum)
{int i,j;EdgeNode *p;for(i=0;i<nodeNum;i++){p=adjlist[i].firstedge;while(p){cout<<'('<<adjlist[i].vertex<<','<<p->adjvex<<')'<<endl;p=p->next;}}
}
//从v出发深度优先遍历可达顶点递归函数
void ALGraph::DFSL(int v)
{int n=vertexNum;int j;EdgeNode *p;if(v>=n||v<0) throw "位置出错";cout<<adjlist[v].vertex<<" ";visited[v]=1;p=adjlist[v].firstedge;while(p){j=p->adjvex;//顶点if(visited[j]==0) DFSL(j);p=p->next;}
}
//从v出发深度优先遍历可达顶点的非递归函数
void ALGraph::DFSL1(int v)
{int S[MaxSize],top=-1,j,n=vertexNum;EdgeNode *p;if(v>=n||v<0) throw "位置出错";cout<<adjlist[v].vertex<<" ";visited[v]=1;S[++top]=v;//v进栈while(top!=-1){v=S[top];//栈顶元素出栈p=adjlist[v].firstedge;while(p){j=p->adjvex;//顶点if(visited[j]==1) p=p->next;else{cout<<adjlist[j].vertex<<" ";visited[j]=1;S[++top]=j;//v进栈p=adjlist[j].firstedge;}}if(j=vertexNum) top--;}
}
//求连通分量数,判断图的连通性
void ALGraph::CountComp(ALGraph g)
{int count=0;int n=g.vertexNum;for(int v=0;v<n;v++){if(visited[v]==0){count++;g.DFSL(v);}}if(count==1) cout<<endl<<"改图是连通的!"<<endl;else cout<<endl<<"改图不连通,连通分量数为:"<<count<<endl;
}
int main()
{int a[9]={0,1,2,3,4,5,6,7,8};ALGraph gr=ALGraph(a,9);//初始化表头gr.createGraph(0,2);gr.createGraph(0,1);gr.createGraph(1,4);gr.createGraph(1,3);gr.createGraph(2,6);gr.createGraph(2,5);gr.createGraph(5,6);gr.createGraph(3,7);gr.createGraph(4,7);gr.createGraph(7,8);gr.displayGraph(9);for(int i=0;i<MaxSize;i++)visited[i]=0;gr.DFSL1(0);//gr.CountComp(gr);return 0;
}






http://chatgpt.dhexx.cn/article/vTqrpFID.shtml

相关文章

图的遍历算法之深度优先遍历(DFS)(C++)

图的深度优先遍历思想是&#xff1a; 从图中某结点出发&#xff0c;访问其某一相邻结点&#xff0c;再访问该结点的相邻结点&#xff0c;直至访问完所有的结点。 形象的比喻就是&#xff1a;一条路走到头&#xff0c;回头再走没走过的路。 可见&#xff0c;深度优先遍历是一…

图的深度优先遍历

一 图遍历介绍 所谓图的遍历&#xff0c;即是对结点的访问。一个图有那么多个结点&#xff0c;如何遍历这些结点&#xff0c;需要特定策略&#xff0c;一般有两种访问策略。 1 深度优先遍历 2 广度优先遍历 二 深度优先遍历基本思想 图的深度优先搜索(Depth First Search…

图的遍历 ——深度优先遍历

图的遍历 ——深度优先遍历 深度优先搜索&#xff08;Depth First Search&#xff0c;DFS&#xff09;是最常见的图搜索方法之一。 深度优先搜索沿着一条路径一直搜索下去&#xff0c;在无法搜索时&#xff0c;回退到刚刚访问过的节点。深度优先遍历是按照深度优先搜索的方式…

二、图的遍历——深度优先遍历

深度优先遍历&#xff0c;也有称为深度优先搜索&#xff0c;简称为DFS。 深度优先遍历其实就是一个递归的过程&#xff0c;它从图中某个顶点ⅴ出发&#xff0c;访问此顶点&#xff0c;然后从V的未被访问的邻接点出发深度优先遍历图&#xff0c;直至图中所有和V有路径相通的顶点…

图的遍历(深度优先遍历DFS,广度优先遍历BFS)以及C语言的实现

遍历的定义&#xff1a; 从已给的连通图中某一顶点出发&#xff0c;沿着一些边访遍图中所有的顶点&#xff0c;且使每个顶点仅被访问一次&#xff0c;就叫做图的遍历&#xff0c;它是图的基本运算&#xff0e; 一:深度优先遍历&#xff08;&#xff24;&#xff26;&#xff…

使用SSM框架上传图片

使用SSM框架上传图片 为了大家方便对照,我上传源码到网盘,有兴趣的自取. ps:其中有一个存储数据的网页,我没删除,可以忽略 链接&#xff1a;https://pan.baidu.com/s/1u24E8mUs4K-raoQgx-ae2A 提取码&#xff1a;java 建数据表 CREATE DATABASE my_resource;USE my_resource…

SSM框架简单介绍

一. SSM框架简介及特征 1.SpringMVC Spring MVC属于SpringFrameWork的后续产品&#xff0c;已经融合在Spring Web Flow 里面。Spring 框架提供了构建 Web 应用程序的全功能 MVC 模块。使用 Spring 可插入的 MVC 架构&#xff0c;从而在使用Spring进行WEB开发时&#xff0c;可…

SSM框架整合详细教程

目录 1. 什么是SSM&#xff1f; 2. SSM整合的时候容器之间如何访问 3. SSM下面的开发步骤 4. SSM整合时候时容易混乱的知识点 1. 什么是SSM&#xff1f; SSM是对三个框架名字的简写&#xff0c;其中第一个S指的是SpringMVC,第二个S指的是Spring&#xff0c;第三个M指的是M…

SSM框架理解

一、作用&#xff1a; 1、 SSM是spingspringMVCmybatis集成的框架。是标准的MVC模式&#xff0c;将整个系统划分为表现层&#xff0c;controller层&#xff0c;service层&#xff0c;DAO层四层。 2、使用spring MVC负责请求的转发和视图管理&#xff0c;spring实现业务对象管理…

SSM框架初探

SSM 框架初探 SSM框架简介对框架的理解为什么使用 SSM 框架 SpringSpringMVCMybatis SSM框架简介 SSM框架一种以java语言作为后端搭建基本语言的应用系统搭建框架。是继SSH(strutsspringhibernate)之后&#xff0c;目前较为主流的Java EE企业级框架&#xff0c;适用于搭建各种大…

SSM框架整合

今天来整合一下SSM三大框架~~ 1、创建一个maven项目 比较简单就不赘述了&#xff0c;创建的时候选择webapp骨架。 用骨架创建的项目&#xff0c;在创建完之后要更新一下web.xml 模板目录&#xff1a;“你的Tomcat安装目录\webapps\ROOT\WEB-INF\web.xml” 2、项目整体结构 按…

SSM框架原理

SSM框架是spring MVC &#xff0c;spring和mybatis框架的整合&#xff0c;是标准的MVC模式&#xff0c;将整个系统划分为表现层&#xff0c;controller层&#xff0c;service层&#xff0c;DAO层四层 使用spring MVC负责请求的转发和视图管理 spring实现业务对象管理&#xff…

SSM框架总结

一&#xff1a;什么是SSM框架&#xff1f; SSM框架是Spring、SpringMVC和MyBatis框架的总结&#xff0c;是比较标准的MVC模式。 标注的SSM框架有四层&#xff1a;dao&#xff08;mapper&#xff09;层、service层、controller层、domain(entity)层。 使用Spring实现业务对象…

SSM框架详解

SSM框架详解 写在前面&#xff1a;当初整理SSM原理时&#xff0c;参考了网上一些前辈的文章&#xff0c;时间久远已经忘记来源&#xff0c;所以文中原理部分如有侵权请联系我删除。 基于SSM框架的仿天猫商城网站电商后台管理系统 本文视频讲解 文章目录 SSM框架详解 一、项…

java ssm框架论文,ssm框架理解

文章简介: SSM框架集简介 spring框架IOC的理解 mybatis框架sqlSessionFactory理解 Tomcat的理解 图解SSM SSM框架常用注解 1.SSM框架集简介 SSM(Spring+SpringMVC+MyBatis)框架集由Spring、MyBatis两个开源框架整合而成(SpringMVC是Spring中的部分内容)。常作为数据源较简单的…

SSM框架详细讲解

SSM框架 文章目录 SSM框架&#xff08;白痴都看完都会&#xff09;介绍SSM框架<原理>一、什么是SSM框架&#xff1f; 1.Spring2.Spring MVC3.Mybatis &#xff08;核心是SqlSession&#xff09;二、代码实战 1.创建配置工程2.代码实战&#xff08;查询记录数&#xff0…

SSM三大框架超详细总结(适合你重新回顾)

目录 1.1 概念 1.2 Mybatis优点 1.3 Mybatis架构 1.4 底层原理 1.5 Mybatis缓存 1.6 常见面试题 2.1 概念 2.2 Spring优点 2.3 Spring架构 2.4 控制反转&#xff08;IOC&#xff09; 2.5 DI依赖注入 2.6 底层原理(常见面试题) 8、如何用基于 Java 配置的方式配置 Spring&#…

SSM框架整合思想及步骤

前言 SSM框架即是将SpringMVC框架、Spring框架、MyBatis框架整合使用。以简化在web开发中繁琐、重复的操作&#xff0c;让开发人员的精力专注于业务处理的开发上。 一、SSM框架的思想 ssm框架根据SpringMVC、Spring、MyBatis三者各自的特性及应用场景对其操作的的业务进行了分…

SSM框架简介

一、Java SSM框架的概念 Java SSM框架即指SpringSpringMVCMyBatis的简称&#xff0c;框架集由Spring、MyBatis两个开源框架整合而成&#xff08;SpringMVC是Spring中的部分内容&#xff09;,常作为数据源较简单的web项目的框架。 相比于之前的SSH&#xff08;SpringStrutsHibe…

SSM框架讲解(史上最详细的文章)

SSM框架&#xff08;白痴都看完都会&#xff09; 文章目录 SSM框架&#xff08;白痴都看完都会&#xff09;介绍SSM框架<原理>一、什么是SSM框架&#xff1f;1.Spring2.Spring MVC3.Mybatis &#xff08;核心是SqlSession&#xff09; 二、代码实战1.创建配置工程2.代码实…