java实现DFS求路径是否有解问题
来源:互联网 发布:免费的儿童教育软件 编辑:程序博客网 时间:2024/06/12 01:33
今天回顾了DFS——Depth First Search——深度优先遍历,这个算法主要有两个用途:一是用于对于未知解的探索,一个典型的例子是走迷宫,也就是我们要列出所有的可能性来穷举,如果找到一条可行之路那么说明我们要解决的问题有戏,如果到最后也没有找到一条可行之路,那么说明我们的问题没有解。二是作为拓扑排序的基石,这一点我们以后再讲。
那么如何来实现DFS算法呢? 我们需要的原料有:结点、边、结点数、以及一个很重要的标记数组——来标记某个结点是否已经被访问过了,这可以避免我们在图中来来回回鬼打墙。
public class DFS {private char[] vertices;private int verticeNum;private boolean[] isVisited;private int[][] edges;
第二步我们通过这个类的一个有参构造函数初始化一下这些原始材料。
public DFS(int n) {vertices = new char[n];verticeNum = n;isVisited = new boolean[n];for(int i = 0; i<n;i++){isVisited[i] = false;}edges = new int[n][n];for (int i = 0; i < n; i++) {for (int j = 0; j < n; j++) {edges[i][j] = 0;}}}
第三步,我们实现加边、加点、访问结点的函数封装,为后续代码的简洁直观打基础
public void addEdge(int i,int j){ //避免加入起点和终点相同的边,其实也就是一个点了……if(i==j)return;edges[i][j] = 1;edges[j][i] = 1;}public void setVertices(char[] vertices){this.vertices = vertices;}public void visit(int i){System.out.print(vertices[i] + " ");}
第四步,是一个很重要很核心的递归函数,基本思想就是,深度访问到某一个结点时,访问它并将之标记为已访问。然后在所有的结点中,找这个结点的未访问过的邻结点(也就是和这个结点 由边连接的结点),对邻接点进行深度上的访问。
public void traverse(int i){isVisited[i] = true;visit(i);for(int j = 0; j<verticeNum;j++){if(edges[i][j] ==1 && isVisited[j] ==false){traverse(j);}}}第五步,在DFS算法的主方法中对图中的每一个结点进行遍历。 我们可以看到,DFSTraverse 函数对每一个结点调用递归函数traverse,traverse函数中有有用到visit函数的地方,我觉得这种封装很棒。
public void DFSTraverse(){for(int i = 0; i< verticeNum;i++){if(!isVisited[i] )traverse(i);}}最后,在main函数中实例化,用例子来试一下。
public static void main(String[] args) {DFS g = new DFS(9);char[] vertices = {'A','B','C','D','E','F','G','H','I'};g.setVertices(vertices); g.addEdge(0, 1); g.addEdge(0, 5); g.addEdge(1, 0); g.addEdge(1, 2); g.addEdge(1, 6); g.addEdge(1, 8); g.addEdge(2, 1); g.addEdge(2, 3); g.addEdge(2, 8); g.addEdge(3, 2); g.addEdge(3, 4); g.addEdge(3, 6); g.addEdge(3, 7); g.addEdge(3, 8); g.addEdge(4, 3); g.addEdge(4, 5); g.addEdge(4, 7); g.addEdge(5, 0); g.addEdge(5, 4); g.addEdge(5, 6); g.addEdge(6, 1); g.addEdge(6, 3); g.addEdge(6, 5); g.addEdge(6, 7); g.addEdge(7, 3); g.addEdge(7, 4); g.addEdge(7, 6); g.addEdge(8, 1); g.addEdge(8, 2); g.addEdge(8, 3); System.out.print("深度优先遍历(递归):"); g.DFSTraverse();}我们可以得到结果:深度优先遍历(非递归):A B C D E F G H I
PS:附赠非递归DFS实现。
其基本思想就是,用到栈,利用栈后进先出的结构特点,每弹出一个结点,就将此结点的未访问过的邻结点放入栈,这样下次从栈中取出的就是往深处走的邻结点,当走到头的时候再取出来的结点就是返回遇到的第一个分岔路口了。
public void DFSNoRecurion(){Stack<Integer> stack = new Stack<Integer>();for(int i = 0; i< verticeNum;i++){if(!isVisited[i] ){stack.push(i);do{int cur = stack.pop();if(!isVisited[cur]){visit(cur);isVisited[cur] = true;for(int j =0;j < verticeNum;j++){if(edges[cur][j] ==1 && !isVisited[j]){stack.push(j);break;}}}}while(!stack.isEmpty());}}}
1 0
- java实现DFS求路径是否有解问题
- poj 3984 迷宫问题 dfs 求迷宫路径
- 邻接矩阵 有向图 判断是否有环 是否连通 DFS C实现~
- 用递归实现求一个迷宫是否有通路
- DFS求迷宫问题
- 邻接表 有向图 是否有环 C实现 (dfs
- Java实现几种最短路径问题
- 《算法导论》DFS求路径算法
- poj 2631(dfs求最长路径)
- DFS求组合的问题~
- 路径输出问题-(DFS)
- 判断N数码问题是否有解
- 八数码问题判断是否有解
- JSP中求关键路径算法及java实现
- 数据结构与算法分析笔记与总结(java实现)--链表16:单链表判断是否有环问题
- java判断json串是否有某个key值问题
- Java静态方法问题,也许无解,求高人看看有没有思路
- java 链表实现(测试是否有环)
- 一些自己用到的学习网站
- 坐在马桶上看算法:只有五行的Floyd最短路算法
- Spring与SpringMVC的关系
- 从零移植uboot 2017 到nuc970(第十五天)
- 算法训练 未名湖边的烦恼
- java实现DFS求路径是否有解问题
- 自然语言处理中CNN模型几种常见的Max Pooling操作
- 关于归并排序的思考
- 字符串的全排列
- 创业公司7步防坑攻略丨技术合伙人你可长点儿心吧!
- 若快识别的python实现示例
- 什么叫表达式?什么叫语句? ~
- CURL
- BZOJ 2242: [SDOI2011]计算器