图的深度优先遍历(Depth First Search)
图的深度优先遍历(Depth First Search)
基本思想
类似于二叉树的先序遍历
假设图中所有结点均未被访问,从初始结点访问,访问其第一个邻接结点,接着以被访问的邻接结点作为初始结点,访问它的第一个邻接结点。
递归的过程。
算法步骤
访问初始结点v,并标记为已访问
查找结点v的第一个邻接结点w
若w存在,则继续执行4,若不存在则回到第1步,从v的下一个结点继续
若w未被访问,对w进行深度优先遍历递归(即把w当做另一个v,然后进行步骤123)
查找结点v的邻接结点w的下一个邻接结点,转到步骤3
无向图深度优先遍历演示
1. 访问A
2. 访问(A的邻接点)C
在第1步访问A之后,接下来应该访问的是A的邻接点,即"C,D,F"中的一个。但在本文的实现中,顶点ABCDEFG是按照顺序存储,C在"D和F"的前面,因此,先访问C。
3. 访问(C的邻接点)B
在第2步访问C之后,接下来应该访问C的邻接点,即"B和D"中一个(A已经被访问过,就不算在内)。而由于B在D之前,先访问B。
4. 访问(C的邻接点)D
在第3步访问了C的邻接点B之后,B没有未被访问的邻接点;因此,返回到访问C的另一个邻接点D。
5. 访问(A的邻接点)F
前面已经访问了A,并且访问完了"A的邻接点C的所有邻接点(包括递归的邻接点在内)";因此,此时返回到访问A的另一个邻接点F。
6. 访问(F的邻接点)G
7. 访问(G的邻接点)E
因此访问顺序是:A -> C -> B -> D -> F -> G -> E
有向图深度优先遍历演示
1. 访问A
2. 访问B
在访问了A之后,接下来应该访问的是A的出边的另一个顶点,即顶点B。
3. 访问C
在访问了B之后,接下来应该访问的是B的出边的另一个顶点,即顶点C,E,F。在本文实现的图中,顶点ABCDEFG按照顺序存储,因此先访问C。
4. 访问E
接下来访问C的出边的另一个顶点,即顶点E。
5. 访问D
接下来访问E的出边的另一个顶点,即顶点B,D。顶点B已经被访问过,因此访问顶点D。
6. 访问F
访问D之后,出边顶点C已访问;回溯到E,E的出边顶点BD均访问;依次回溯到B,B的出边顶点CF中F未访问,所以访问F。
7. 访问G
因此访问顺序是:A -> B -> C -> E -> D -> F -> G
算法实现
import java.util.ArrayList;
import java.util.Arrays;public class GraphTraversal {private ArrayList<Object> nodeList;//存储结点的集合private int[][] edges;//结点与结点之间的连线关系private int numOfEdges;//图中连线数量private boolean[] isVisited;//标记结点是否被访问public GraphTraversal(int n){//初始化矩阵和顶点列表nodeList = new ArrayList<Object>(n);edges = new int[n][n];numOfEdges = 0;isVisited = new boolean[n];}public static void main(String[] args) {//声明图中结点int n = 7;String nodes[] = {"A","B","C","D","E","F","G"};//创建一个无向图GraphTraversal undirectedGraph = new GraphTraversal(n);//将顶点添加到图中if(undirectedGraph.addNodes(nodes) > 0){//添加顶点间的关系undirectedGraph.insertUndirectedEdge(0, 3, 1);undirectedGraph.insertUndirectedEdge(0, 2, 1);undirectedGraph.insertUndirectedEdge(0, 5, 1);undirectedGraph.insertUndirectedEdge(2, 1, 1);undirectedGraph.insertUndirectedEdge(2, 3, 1);undirectedGraph.insertUndirectedEdge(5, 6, 1);undirectedGraph.insertUndirectedEdge(6, 4, 1);//显示邻接矩阵System.out.println("无向图邻接矩阵:");undirectedGraph.showGraph();//无向图深度优先遍历System.out.println("无向图深度优先遍历:");undirectedGraph.dfs();}//创建一个有向图GraphTraversal directedGraph = new GraphTraversal(n);//添加结点到图中if (directedGraph.addNodes(nodes) > 0){//添加结点之间的关系directedGraph.insertDirectedEdge(0,1,1);directedGraph.insertDirectedEdge(1,2,1);directedGraph.insertDirectedEdge(1,4,1);directedGraph.insertDirectedEdge(1,5,1);directedGraph.insertDirectedEdge(2,4,1);directedGraph.insertDirectedEdge(3,2,1);directedGraph.insertDirectedEdge(4,3,1);directedGraph.insertDirectedEdge(4,1,1);directedGraph.insertDirectedEdge(5,6,1);//显示邻接矩阵System.out.println("有向图邻接矩阵:");directedGraph.showGraph();//有向图深度优先遍历System.out.println("有向图深度优先遍历:");directedGraph.dfs();}}//将结点添加到图中public int addNodes(Object[] nodes){for (Object node : nodes){nodeList.add(node);}return nodeList.size();}//创建无向图结点关系public void insertUndirectedEdge(int v1, int v2, int weight){edges[v1][v2] = weight;edges[v2][v1] = weight;numOfEdges++;}//创建有向图结点关系public void insertDirectedEdge(int v1, int v2, int weight){edges[v1][v2] = weight;numOfEdges++;}//显示邻接矩阵public void showGraph(){for (int[] link : edges){System.out.println(Arrays.toString(link));}}//根据初始结点获取第一个邻接结点public int getFirstNeighbor(int v1){for(int v2 = 0; v2 < edges.length; v2++){if (edges[v1][v2] > 0){return v2;}}return -1;}//根据前一个邻接结点获取下一个邻接结点public int getNextNeighbor(int v1, int v2){for (int j = v2 + 1; j < edges.length; j++){//从上一个结点[v1]开始找下一个结点if (edges[v1][j] > 0){//若 v1 到 j 的连线存在,则存在下一个结点return j;}}return -1;//说明不存在下一个结点}//dfs深度优先遍历public void dfs(boolean[] isVisited, int v){//输出当前访问的起始结点System.out.print(nodeList.get(v) + "->");//根据索引值获取List中结点值//当前起始结点标记为已访问isVisited[v] = true;//访问起始结点的第一个邻接结点int w = getFirstNeighbor(v);while (w != -1){//说明存在第一个邻接结点if (!isVisited[w]){//未被标记为已访问dfs(isVisited, w);//把当前的邻接结点作为起始结点,递归执行深度遍历算法}//如果w结点已经被访问,则寻找下一个邻接结点w = getNextNeighbor(v, w);}}//对 dfs 重载,使其对所有结点进行 dfspublic void dfs(){for (int i = 0; i < nodeList.size(); i++){if (!isVisited[i]){//结点未被标记为已访问dfs(isVisited, i);//第 i 个结点作为初始结点进行 dfs}}System.out.println();}
}
图的深度优先遍历(Depth First Search)相关推荐
- 深度优先遍历(Depth First Search, 简称 DFS)
正文开始: 深度优先遍历(Depth First Search, 简称 DFS) 与广度优先遍历(Breath First Search)是图论中两种非常重要的算法,生产上广泛用于拓扑排序,寻路(走迷 ...
- 分别用邻接矩阵和邻接表实现图的深度优先遍历和广度优先遍历_数据结构|图的邻接表与深度、广度优先搜索
线性存储元素时,元素的关系也同时确定了.而非线性数据结构就不同了,需要同时考虑存储数据元素和数据元素的关系. 由于图的结构比较复杂,任意两个顶点之间都可能存在联系,因此无法以数据元素在存储区中的物理位 ...
- 实验报告C语言实现图的深度遍历,图的深度优先遍历的C语言实现.pdf
图的深度优先遍历的C语言实现.pdf 维普资讯 九 江 职 业 技 术 学 院 学 报 JournalofJiujiangVocational&TechnicalCollege 2004.2 ...
- 数据结构 图的深度优先遍历 C
分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! Bool ...
- java语言实现图的深度优先遍历
java语言实现图的深度优先遍历: 图的存储采用的是邻接矩阵存储的方式,对下面的无向图进行遍历 代码如下: public class Deep {int count=0;public static v ...
- 广度优先搜索生成树怎么画_图的深度优先遍历与广度优先遍历以及最小生成树...
图的深度优先遍历 题目:写出附从每个顶点出发的一次深度优先搜索遍历序列.在纸上画出遍历过程和序列,提交截图. 错误回答 从A点开始遍历:0124-01324-0134-0324-034 从B点开始遍历 ...
- C++实现图的深度优先遍历和广度优先遍历
图的深度和广度优先遍历 图的深度优先遍历 1.算法思想 2.邻接矩阵构造图 3.邻接表构造图 图的广度优先遍历 1.算法思想 2.邻接矩阵构造图 图的深度优先遍历 1.算法思想 (1)从图中的某个初始 ...
- 分别用邻接矩阵和邻接表实现图的深度优先遍历和广度优先遍历_数据结构与算法学习笔记:图...
图: 图结构区别于线性结构和树型结构,区别可见下图 逻辑上的图(graph)结构由顶点(vertex)和边(edge)组成. 一个图结构G包含顶点集合V和边集合E,任何两个顶点之间可以有一个边表示两者 ...
- 邻接矩阵存储图的深度优先遍历
练习6.1 邻接矩阵存储图的深度优先遍历 (20 分) 试实现邻接矩阵存储图的深度优先遍历. 函数接口定义: void DFS( MGraph Graph, Vertex V, void (*Visi ...
最新文章
- kubernetes Helm
- Python的浅拷贝和深拷贝
- android动态jar,Android动态加载Jar(包含第三方依赖Jar)
- 【Ubuntu-apt-换源】ubuntu系统换源后使用apt-get update时一直0%[执行中]
- [Java基础]Object类的常用方法
- opencv:灰色和彩色图像的像素直方图及直方图均值化的实现与展示
- 如何获得Windows聚焦壁纸0726
- JavaSE基础笔记十二
- Ubuntu13.04配置优化(四)转贴
- Cocos2dx游戏源码合集
- 全网最全sql入门经典
- 代码整洁之道-编写 Pythonic 代码
- java数据类型简介
- Linux虚拟机挂载新的硬盘
- word查重_2020论文查重倾情分享 | 查重注意要点
- 为什么微信无法打开html文件,微信网页版打不开怎么办?微信网页版无法打开的解决方法...
- android qq音乐无法连接网络连接,qq音乐不能播放_qq音乐为什么老是提示说歌曲无效或网络连接失败呢?...
- export default function和export function的区别
- Android Device Moniter部分问题的解决办法:
- HDU-圆桌会议问题
热门文章
- 状态迁移法你还不会?看看这篇文章
- Java语言高级(第一部分)常用API 继承与多态 ->(个人学习记录笔记)
- SSM整合(Spring + SpringMVC + Mybatis)
- 激光清洗机能清洗什么
- 【OpenCV案例实战分享】关于图像处理的一些基本操作之二值化、图像加噪处理......
- 我的世界服务器自建主城,为纪念去世的服务器创建人,《我的世界》玩家们竖起了告示牌...
- 360安全路由开启预约 双频路由器售价99元
- 4.1 keras基础实例 手写数字识别
- EL表达式判断Map是否为空和map的取值
- C语言程序设计(本) 阶段作业,武汉理工大学继续教育《C语言程序设计(本)》在线作业答案...