图的深度优先遍历算法(DFS)
搜索算法有很多种,本次文章主要分享图(无向图)的深度优先算法。深度优先算法(DFS)主要是应用于搜索中,早期是在爬虫中使用。其主要的思想有如下:
1.先访问一个节点v,然后标记为已被访问过
2.找到第一个节点的邻接节点w
3.如果第一个邻接节点w存在就走第4步,如果不存在就返回第一个节点v,从v的其他节点继续开始
4.如果节点w存在就怕判断该节点是否被访问过,如果没有被访问过就进行升读优先遍历(重复1,2,3)
5.查找节点v的邻接节点w的邻接节点(继续执行3)

先创建一个图,主要使用邻接矩阵(二位数组)进行存储节点到节点之间的关系。如果A可以到达B那么用1表示,不可以就用0进行表示。
而二维数组的长度是节点的个数,列如有n个节点那么二位数组的长度为Array[n][n]。
创建图以及深度优先算法的代码如下:
1 public class Graph {
2
3 //创建一个集合用来存放顶点
4 private ArrayList<String> arrayList;
5 //创建一个二位数组来作为邻接矩阵
6 private int[][] TwoArray;
7 //边的数目
8 private int numOfEdges;
9 //使用一个数组记录节点是否被访问过
10 private boolean[] isVisted;
11 public static void main(String[] args) {
12 Graph graph = new Graph(5);
13 //测试
14 String[] ver={"A","B","C","D","E"};
15 //将节点放到集合中
16 for (String s : ver) {
17 graph.InsertVex(s);
18 }
19 //设置边
20 //A-B A-C B-C B-D B-E
21 graph.InsertEdeges(0,1,1);
22 graph.InsertEdeges(0,2,1);
23 graph.InsertEdeges(1,2,1);
24 graph.InsertEdeges(1,3,1);
25 graph.InsertEdeges(1,4,1);
26 //显示
27 graph.Show();
28 graph.DFS();
29 }
30
31 //初始化数据
32 public Graph(int n){
33 arrayList=new ArrayList<>(n);
34 TwoArray=new int[n][n];
35 numOfEdges=0;
36 isVisted=new boolean[n];
37 }
38
39 /**
40 * 根据节点的下标返回第一个邻接节点的下标
41 * @param index 节点的下标
42 * @return
43 */
44 public int getFirstVex(int index){
45 for (int i = 0; i < arrayList.size(); i++) {
46 if(TwoArray[index][i]!=0){
47 return i;
48 }
49 }
50 return -1;
51 }
52
53 /**
54 * 根据前一个节点下标获取下一个节点的下标
55 * @param v1 找到的第一个节点的
56 * @param v2 找到的第一个邻接节点并且被访问过的
57 * @return
58 */
59 public int getNextVex(int v1,int v2){
60 for (int i = v2+1; i < numEdges(); i++) {
61 if(TwoArray[v1][i]!=0){
62 return i;
63 }
64 }
65 return -1;
66 }
67
68 /**
69 * 深度优先算法的实现
70 * @param isVisted
71 * @param i
72 */
73 public void DFS(boolean[] isVisted,int i){
74 //先访问该节点
75 System.out.print(getValue(i)+"->");
76 //将节点设置为已经访问
77 isVisted[i]=true;
78 //查找该节点的第一个邻接节点
79 int firstVex = getFirstVex(i);
80 //不等于-1说明是存在的
81 while (firstVex!=-1) {
82 //如果存在且没有被访问过就进行访问
83 if (!isVisted[firstVex]) {
84 DFS(isVisted, firstVex);
85 }
86 firstVex = getNextVex(i, firstVex);
87 }
88 }
89
90 public void DFS(){
91 for (int i = 0; i <arrayList.size(); i++) {
92 if(!isVisted[i]){
93 //进行回溯
94 DFS(isVisted,i);
95 }
96 }
97 }
98 /**
99 * 添加节点
100 * @param vex
101 */
102 public void InsertVex(String vex){
103 arrayList.add(vex);
104 }
105
106 /**
107 * 设置边
108 * @param v1 第一个节点对应的下标
109 * @param v2 第二节点对应的下标
110 * @param weight 两个节点对应的权值
111 */
112 public void InsertEdeges(int v1,int v2,int weight){
113 TwoArray[v1][v2]=weight;
114 TwoArray[v2][v1]=weight;
115 numOfEdges++;
116 }
117
118 /**
119 * 返回节点对应的个数
120 * @return
121 */
122 public int numVex(){
123 return arrayList.size();
124 }
125
126 /**
127 * 返回边的总个数
128 * @return
129 */
130 public int numEdges(){
131 return numOfEdges;
132 }
133
134 /**
135 * 显示邻接矩阵(图的展示)
136 */
137 public void Show(){
138 for (int[] ints : TwoArray) {
139 System.out.println(Arrays.toString(ints));
140 }
141 }
142
143 /**
144 * 根据下标获取对应的数据
145 * @param i 下标
146 * @return
147 */
148 public String getValue(int i){
149 return arrayList.get(i);
150 }
151
152 public int getWeight(int v1,int v2){
153 int weight=TwoArray[v1][v2];
154 return weight;
155 }
156 }
代码执行结果如下:

图的深度优先遍历算法(DFS)的更多相关文章
- 图的深度优先遍历(DFS)和广度优先遍历(BFS)
body, table{font-family: 微软雅黑; font-size: 13.5pt} table{border-collapse: collapse; border: solid gra ...
- 图文详解两种算法:深度优先遍历(DFS)和广度优先遍历(BFS)
参考网址:图文详解两种算法:深度优先遍历(DFS)和广度优先遍历(BFS) - 51CTO.COM 深度优先遍历(Depth First Search, 简称 DFS) 与广度优先遍历(Breath ...
- 图的深度优先遍历DFS
图的深度优先遍历是树的前序遍历的应用,其实就是一个递归的过程,我们人为的规定一种条件,或者说一种继续遍历下去的判断条件,只要满足我们定义的这种条件,我们就遍历下去,当然,走过的节点必须记录下来,当条件 ...
- 图的深度优先遍历(DFS) c++ 非递归实现
深搜算法对于程序员来讲是必会的基础,不仅要会,更要熟练.ACM竞赛中,深搜也牢牢占据着很重要的一部分.本文用显式栈(非递归)实现了图的深度优先遍历,希望大家可以相互学习. 栈实现的基本思路是将一个节点 ...
- 图的深度优先遍历(DFS)—递归算法
实验环境:win10, DEV C++5.11 实验要求: 实现图的深度优先遍历 实验代码: #include <iostream> #define maxSize 255 #includ ...
- 数据结构——图的深度优先遍历(邻接矩阵表示+java版本)
1.深度优先遍历(DFS) 图的深度优先遍历本质上是一棵树的前序遍历(即先遍历自身,然后遍历其左子树,再遍历右子树),总之图的深度优先遍历是一个递归的过程. 如下图所示,左图是一个图,右图是图的深度 ...
- PTA 邻接矩阵存储图的深度优先遍历
6-1 邻接矩阵存储图的深度优先遍历(20 分) 试实现邻接矩阵存储图的深度优先遍历. 函数接口定义: void DFS( MGraph Graph, Vertex V, void (*Visit)( ...
- 图论 - 图的深度优先遍历c++实现
图的深度优先遍历c++实现 深度优先搜索 邻接矩阵的创建 int i, j, m, a, b; cin >> n >> m; //初始化二维矩阵 for (i = 1; i & ...
- 图的广度优先遍历算法(BFS)
在上一篇文章我们用java演示了图的数据结构以及图涉及到的深度优先遍历算法,本篇文章将继续演示图的广度优先遍历算法.广度优先遍历算法主要是采用了分层的思想进行数据搜索.其中也需要使用另外一种数据结构队 ...
随机推荐
- Refit集成consul在asp.net core中的实践
前言 github:https://github.com/alphayu/ Refit.WebApiClient.Feign等都是支持声名式的Restful服务调用的开源组件. 这个几个组件都综合研究 ...
- 关于echarts中的noDataLoadingOption——loading动画的问题
在最近的一个项目中用到echarts这个插件,其中关于noDataLoadingOption配置项的问题让我困惑了好长时间.经过蛋疼的查找下,终于搞明白是版本的原因. 且看官网的介绍:ECharts, ...
- 项目中处理数据常用Excel公式
="'"&A1&"'," 需求:是大佬给了excel,里面是700多个单号,要我从生产的数据库中查询出每个单号对应的类型,这时需要查数据库,我决 ...
- Nginx安装,开箱即用?
一.官网 首页:http://nginx.org/ 下载地址:http://nginx.org/download 安装文档:http://nginx.org/en/docs/install.html ...
- LRU缓存的实现
文章目录 LRU简介 LRU算法分析 实现代码 节点类 双向链表 LRUCache类 测试类 总结 LRU简介 LRU是"Least Recently Used"的简写,意思是最近 ...
- SpringMVC文件的上传与下载实现
单文件上传 首先创建项目,开发工具是IDEA,选择Spring项目,勾选上Spring和SpringMVC. 然后命名,最后完成. 默认生成配置文件在web/WEB-INF下. 首先导入需要的jar包 ...
- SpringBoot嵌入式Servlet容器
SpringBoot默认是将Tomcat作为嵌入式的servlet容器. 问题: 如何修改嵌入式的servlet容器? 1)在配置文件中设置对应的属性值 server.port=8081 # Tomc ...
- 【Java】网络编程之NIO
简单记录 慕课网-解锁网络编程之NIO的前世今生 & 一站式学习Java网络编程 全面理解BIO/NIO/AIO 内容概览 文章目录 1.[了解] NIO网络编程模型 1.1.NIO简介 1. ...
- kubernets之pod的标签的使用
一 对于kubernets里面的资源标记完成之后的使用 1 node节点标签的应用(将资源调度到特定的节点上) #kubia-gpu.ymlapiVersion: v1 kind: Pod metad ...
- C# 中的动态类型
翻译自 Camilo Reyes 2018年10月15日的文章 <Working with the Dynamic Type in C#> [1] .NET 4 中引入了动态类型.动态对象 ...