搜索算法有很多种,本次文章主要分享图(无向图)的深度优先算法。深度优先算法(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)的更多相关文章

  1. 图的深度优先遍历(DFS)和广度优先遍历(BFS)

    body, table{font-family: 微软雅黑; font-size: 13.5pt} table{border-collapse: collapse; border: solid gra ...

  2. 图文详解两种算法:深度优先遍历(DFS)和广度优先遍历(BFS)

    参考网址:图文详解两种算法:深度优先遍历(DFS)和广度优先遍历(BFS) - 51CTO.COM 深度优先遍历(Depth First Search, 简称 DFS) 与广度优先遍历(Breath ...

  3. 图的深度优先遍历DFS

    图的深度优先遍历是树的前序遍历的应用,其实就是一个递归的过程,我们人为的规定一种条件,或者说一种继续遍历下去的判断条件,只要满足我们定义的这种条件,我们就遍历下去,当然,走过的节点必须记录下来,当条件 ...

  4. 图的深度优先遍历(DFS) c++ 非递归实现

    深搜算法对于程序员来讲是必会的基础,不仅要会,更要熟练.ACM竞赛中,深搜也牢牢占据着很重要的一部分.本文用显式栈(非递归)实现了图的深度优先遍历,希望大家可以相互学习. 栈实现的基本思路是将一个节点 ...

  5. 图的深度优先遍历(DFS)—递归算法

    实验环境:win10, DEV C++5.11 实验要求: 实现图的深度优先遍历 实验代码: #include <iostream> #define maxSize 255 #includ ...

  6. 数据结构——图的深度优先遍历(邻接矩阵表示+java版本)

    ​1.深度优先遍历(DFS) 图的深度优先遍历本质上是一棵树的前序遍历(即先遍历自身,然后遍历其左子树,再遍历右子树),总之图的深度优先遍历是一个递归的过程. 如下图所示,左图是一个图,右图是图的深度 ...

  7. PTA 邻接矩阵存储图的深度优先遍历

    6-1 邻接矩阵存储图的深度优先遍历(20 分) 试实现邻接矩阵存储图的深度优先遍历. 函数接口定义: void DFS( MGraph Graph, Vertex V, void (*Visit)( ...

  8. 图论 - 图的深度优先遍历c++实现

    图的深度优先遍历c++实现 深度优先搜索 邻接矩阵的创建 int i, j, m, a, b; cin >> n >> m; //初始化二维矩阵 for (i = 1; i & ...

  9. 图的广度优先遍历算法(BFS)

    在上一篇文章我们用java演示了图的数据结构以及图涉及到的深度优先遍历算法,本篇文章将继续演示图的广度优先遍历算法.广度优先遍历算法主要是采用了分层的思想进行数据搜索.其中也需要使用另外一种数据结构队 ...

随机推荐

  1. 微信小程序--仿微信小程序朋友圈Pro(内容发布、点赞、评论、回复评论)

    微信小程序--仿微信小程序朋友圈Pro(内容发布.点赞.评论.回复评论) 项目开源地址M朋友圈Pro 求个Star 项目背景 ​ 基于原来的开源项目 微信小程序仿朋友圈功能开发(发布.点赞.评论等功能 ...

  2. vue中Echarts的使用-自选效果

    由于项目要求使用数据图,于是我选择了我们的Echarts用来实现效果 一:全局安装Echarts npm install echarts --save(这个安装的是最新的版本有时候回报init未定义) ...

  3. Hbase性能调优(二)

    一.HBase关键参数配置指导 如果同时存在读和写的操作,这两种操作的性能会相互影响.如果写入导致的flush和Compaction操作频繁发生,会占用大量的磁盘IO操作,从而影响读取的性能.如果写入 ...

  4. 《Go 语言并发之道》读后感 - 第一章

    <Go 语言并发之道>读后感 - 第一章 前言 人生路漫漫,总有一本书帮助你在某条道路上打通任督二脉,<Go 语言并发之道>就是我作为一个 Gopher 道路上的一本打通任督二 ...

  5. 小米11和iPhone11 哪个好

    小米11:搭载最新一代三星的AMOLED屏幕,120Hz屏幕刷新iPhone11采用6.1英寸的分辨率1792828的LCD屏幕小米手机爆降800 优惠力度空前机会不容错过https://www.xi ...

  6. Redis缓存篇(四)缓存异常

    这一节,我们来学习一下缓存异常.缓存异常有四种类型,分别是缓存和数据库的数据不一致.缓存雪崩.缓存击穿和缓存穿透. 下面通过了解这四种缓存异常的原理和应对方法. 缓存和数据库的数据不一致 缓存和数据库 ...

  7. C++把数字排序

    C++把数字排序 描述 思路 代码 描述 如题,详细如下: 输入不超过1024个数字,以特殊数字结尾,如(-999),把数字从小到大排序. 思路 目前,我们有两种思路可以写: 1是 在输入的时候,排序 ...

  8. 为Github仓库添加Github Actions实现持续集成: Android apk自动编译发布以及github pages同步推送coding.net

    内容转载自我的博客 目录 说明 1. 编写Android项目的CI配置文件 2. 编写Jekyll项目的CI配置文件 2.1 配置coding.net 2.2 配置github 2.3 自动部署到co ...

  9. 【JavaWeb】JSTL 标签库

    JSTL 标签库 简介 JSTL(JSP Standard Tag Library),即 JSP 标准标签库.标签库是为了替换代码脚本,使得整个 jsp 页面变得更加简洁. JSTL 有五个功能不同的 ...

  10. python函数1-函数基础