- 浏览: 600376 次
- 来自: ...
文章分类
最新评论
-
lgh1992314:
相同的元素呢
一种离散化方法 -
HelloSummerR:
圆心的位置是随机的,于是圆的部分会落到canvas外,那样就显 ...
HTML5 Canvas学习笔记(1)处理鼠标事件 -
hlstudio:
好久没见到sokuban了,这有个java版的,带源码,可以参 ...
求推箱子的最小步数(java) -
肖泽文:
太好了,谢谢你。。有中文注释!
HTML5 推箱子游戏过关演示动画 -
swm8023:
删除操作,将最后一个叶子节点插入后也有可能上浮吧
彻底弄懂最大堆的四种操作(图解+程序)(JAVA)
当每个任务有前后置关系时,需要找到一种满足前后置关系的路线,将任务完成。
如果将每个任务看成一个节点,任务之间的前后置关系表示为有向图时,这种路线顺序叫做为图进行拓扑排序。也叫关键路径分析。
比如有很多任务T1,T2,....
这些任务又是相互关联的,比如Tj完成前必须要求Ti已完成,这样T1,T2....序列关于这样的先决条件构成一个图,其中如果Ti必须要先于Tj完成,那么<Ti,Tj>就是该图中的一条路径,路径长度为1的就是一条边。拓扑排序就是把这些任务按照完成的先后顺序排列出来。显然,这样的顺序可能不是唯一的,比如Tk,Tl如果没有在一条路径上,那么他们之间的顺序是任意的。
当从某顶点v出发的DFS搜索完成时,v的所有后继必定均已被访问过(想像它们均已被删除),此时的v相当于是无后继的顶点,因此在DFS算法返回之前输出顶点v即可得到 DAG的逆拓扑序列。
其中第一个输出的顶点必是无后继(出度为0)的顶点,它应是拓扑序列的最后一个顶点。若希望得到的不是逆拓扑序列,同样可增加T来保存输出的顶点。假设T是栈。
利用DFS求拓扑序列的抽象算法可描述为:
void DFSTopSort(G,i,T){//i是搜索的出发点,T是栈
int j;
visited[i]=TRUE; //访问i
for(所有i的邻接点j)//即<i,j>∈E(G)
if(!visited[j])
DFSTopSort(G,j,T);
Push(&T,i); //从i出发的搜索已完成,输出i
}
看看下图的一个拓扑序列:
[c1, c4, c0, c2, c3, c5, c6, c7, c8]
下载源文件:
如果将每个任务看成一个节点,任务之间的前后置关系表示为有向图时,这种路线顺序叫做为图进行拓扑排序。也叫关键路径分析。
比如有很多任务T1,T2,....
这些任务又是相互关联的,比如Tj完成前必须要求Ti已完成,这样T1,T2....序列关于这样的先决条件构成一个图,其中如果Ti必须要先于Tj完成,那么<Ti,Tj>就是该图中的一条路径,路径长度为1的就是一条边。拓扑排序就是把这些任务按照完成的先后顺序排列出来。显然,这样的顺序可能不是唯一的,比如Tk,Tl如果没有在一条路径上,那么他们之间的顺序是任意的。
当从某顶点v出发的DFS搜索完成时,v的所有后继必定均已被访问过(想像它们均已被删除),此时的v相当于是无后继的顶点,因此在DFS算法返回之前输出顶点v即可得到 DAG的逆拓扑序列。
其中第一个输出的顶点必是无后继(出度为0)的顶点,它应是拓扑序列的最后一个顶点。若希望得到的不是逆拓扑序列,同样可增加T来保存输出的顶点。假设T是栈。
利用DFS求拓扑序列的抽象算法可描述为:
void DFSTopSort(G,i,T){//i是搜索的出发点,T是栈
int j;
visited[i]=TRUE; //访问i
for(所有i的邻接点j)//即<i,j>∈E(G)
if(!visited[j])
DFSTopSort(G,j,T);
Push(&T,i); //从i出发的搜索已完成,输出i
}
看看下图的一个拓扑序列:
[c1, c4, c0, c2, c3, c5, c6, c7, c8]
public enum VertexState { UNVISITED,VISITED,PASSED;//未访问,已访问,已经过 } import java.util.Set; import java.util.List; import java.util.HashSet; import java.util.ArrayList; import java.util.Collections; //顶点类 class Vertex { private String label; private VertexState state;//顶点状态 public Vertex(String lab) { label = lab; state = VertexState.UNVISITED; } public VertexState getState(){ return state; } public void setState(VertexState state){ this.state=state; } public String toString(){ return label; } } //有向图的邻接矩阵实现 class Graph { private final int MAX_VERTS = 30; private Vertex vertexList[]; // 存放顶点的数组 private int adjMat[][]; // 邻接矩阵 private int nVerts; // 当前的顶点数 public Graph() { vertexList = new Vertex[MAX_VERTS]; adjMat = new int[MAX_VERTS][MAX_VERTS]; nVerts = 0; for(int y=0; y<MAX_VERTS; y++) for(int x=0; x<MAX_VERTS; x++) adjMat[x][y] = 0; } public void addVertex(Vertex v)//在图中添加一个顶点 { vertexList[nVerts++] = v; } //在图中增加一条边,从start到end public void addEdge(int start, int end) { adjMat[start][end] = 1; } /** * 返回v顶点所关联的邻结点 * @param v * @return */ private Set<Vertex> getNeighbors(Vertex v){ Set<Vertex> vSet = new HashSet<Vertex>(); int index=getIndex(v); if(index==-1) return null; for(int i=0;i<nVerts;i++) if(adjMat[index][i]==1) vSet.add(vertexList[i]); return vSet; } //返回顶点在vertexList数组中的索引 private int getIndex(Vertex v){ for(int i=0;i<nVerts;i++) if(vertexList[i]==v) return i; return -1; } /** * 全部节点设为未访问 */ private void allUnVisted(){ Vertex v=null; int len = nVerts; for(int i = 0; i < len ; i++){ v = vertexList[i]; if(v.getState() != VertexState.UNVISITED){ v.setState(VertexState.UNVISITED); } } } private boolean containsVertex(Vertex v){ int index=getIndex(v); if(index!=-1) return true; else return false; } private VertexState getState(Vertex v){ return v.getState(); } private VertexState setState(Vertex v, VertexState state) { VertexState preState = v.getState(); v.setState(state); return preState; } /** * 深度优先遍历一个顶点 * @param * @param graph * @param v * @param checkCycle * @return */ public List<Vertex> dfs(Vertex v,boolean checkCycle){ allUnVisted(); List<Vertex> vList = new ArrayList<Vertex>(); dfsHandler(v,checkCycle,vList); return vList; } private void dfsHandler(Vertex v,boolean checkCycle,List<Vertex> vList){ Set<Vertex> neighbors = null; if(!containsVertex(v)){ throw new IllegalStateException("不存在该顶点"); } setState(v, VertexState.PASSED); neighbors = getNeighbors(v); VertexState state = null; for(Vertex neighbor : neighbors){ state = getState(neighbor); if(state == VertexState.UNVISITED){//未遍历, // System.out.println(neighbor+","); dfsHandler(neighbor, checkCycle, vList); }else if(state == VertexState.PASSED && checkCycle){// throw new IllegalStateException("存在一个环"); } } setState(v, VertexState.VISITED);//访问结束设为已访问 vList.add(v); // System.out.println("++"+v); } /** * 图的拓扑排序 */ public List<Vertex> topo(){ List<Vertex> vList = new ArrayList<Vertex>(); allUnVisted(); for(int i=0;i<nVerts;i++){ if(getState(vertexList[i]) == VertexState.UNVISITED){ try{ dfsHandler(vertexList[i], true, vList); }catch (IllegalStateException e) { throw new IllegalStateException("图有一个环"); } } } Collections.reverse(vList); return vList; } } public class DFSApp { public static void main(String[] args) { Graph theGraph = new Graph(); Vertex v1=new Vertex("c0"); Vertex v2=new Vertex("c1"); Vertex v3=new Vertex("c2"); Vertex v4=new Vertex("c3"); Vertex v5=new Vertex("c4"); Vertex v6=new Vertex("c5"); Vertex v7=new Vertex("c6"); Vertex v8=new Vertex("c7"); Vertex v9=new Vertex("c8"); theGraph.addVertex(v1); // 0 theGraph.addVertex(v2); // 1 theGraph.addVertex(v3); // 2 theGraph.addVertex(v4); // 3 theGraph.addVertex(v5); // 4 theGraph.addVertex(v6); // 5 theGraph.addVertex(v7); // 6 theGraph.addVertex(v8); // 7 theGraph.addVertex(v9); // 8 theGraph.addEdge(0, 6); // c0->c6 theGraph.addEdge(0, 2); // c0->c2 theGraph.addEdge(3, 5); // c3->c5 theGraph.addEdge(3, 8); // c3->c8 theGraph.addEdge(1, 2); // c1->c2 theGraph.addEdge(1, 4); // c1->c4 theGraph.addEdge(2, 3); // c2->c3 theGraph.addEdge(6, 7); // c6->c7 theGraph.addEdge(7, 8); // c7->c8 theGraph.addEdge(4, 3); // c4->c3 theGraph.addEdge(4, 5); // c4->c5 //theGraph.addEdge(3, 1); // c3->c1 System.out.print("Visits: "); List<Vertex> vl=theGraph.topo(); // List<Vertex> vl=theGraph.dfs(v1,false); System.out.println(vl); } }
下载源文件:
发表评论
-
图的深搜+回溯练习题:POJ2197
2013-01-18 15:53 1644POJ 2197题意: 给定n个城市及其之间的距离,以及距 ... -
图的练习题(有解答)
2012-12-27 22:23 26521. 填空题 ⑴ 设无向图G ... -
邻接表实现图的广搜和深搜(java模板)
2012-12-11 17:04 2452//邻接表实现图的广搜和深搜(java模板) impor ... -
邻接矩阵实现图的广搜和深搜(java模板)
2012-12-10 20:37 1909经常要用到,放到这里备用!! //邻接矩阵实现图的广搜和深搜 ... -
如何求无向图的最小环
2012-11-13 19:02 2778POJ1734 题意:给定一个N个点的无向图,求一个最小环(各 ... -
深度优先搜索输出有向图中的所有环(JAVA)
2012-11-06 14:22 9618如图:求出有向图的所有环。 import java.uti ... -
三种算法(Floyd、Dijkstra、SPFA)求单源点最短路径。
2012-11-05 13:15 1845题(HDU2544): 在每年的校赛里,所有进入决赛 ... -
Dijkstra算法解HDU1874
2012-11-05 10:15 1343Dijkstra算法是用来解 ... -
SPFA算法求单源最短路径
2012-11-04 23:00 1922很多时候,给定的图存在负权边,这时类似Dijkstra等算法 ... -
图解Bellman-Ford算法
2012-11-03 19:39 5922Bellman-Ford算法: ... -
Bellman-Ford算法教学PPT
2012-11-03 12:06 1451Dijkstra算法是处理单源最短路径的有效算法,但它 ... -
昆虫的同性恋
2012-11-01 19:21 1393题目大意: 输入一个数t,表示测试组数。然后每组第一行两 ... -
拓扑排序入门练习
2012-11-01 16:51 1576拓扑排序简单来说 ... -
并查集入门精讲,实例2个(JAVA)
2012-10-30 14:47 4043一、什么是并查集 ... -
无前趋的顶点优先的拓扑排序方法(JAVA)
2012-10-28 20:20 1856无前趋的顶点优先的拓扑排序方法 该方法的每一步总是输 ... -
Kruskal算法和prim算法求最小生成树学习小结(JAVA)
2012-10-26 14:02 5037prim算法是用来实现图最小生成树的2种常用方法之一,P ... -
图的邻接表存储及遍历(JAVA)
2012-10-10 10:58 5420为图的每个顶点所发出的边建立一个单链表,用一顶点数组存储 ... -
弗洛伊德(Floyd)算法求任意两点间的最短路径
2012-10-01 07:46 6289Floyd-Warshall算法(Floyd-Warsha ... -
单源最短路径( Dijkstra算法)JAVA实现
2012-09-14 14:30 9109单源最短路径问题,即在图中求出给定顶点到其它任一顶 ... -
最小生成树:Kruskal(克鲁斯卡尔)算法实现(java)
2012-09-01 20:50 2631算法描述:Kruskal(克鲁斯卡尔)算法需要对图的边进行访问 ...
相关推荐
深度优先搜索(DFS, Depth-First Search)是一种用于遍历或搜索树或图的算法,尤其在处理有向图中的环问题时表现出色。在这个场景下,我们的目标是找到有向图中的所有环。Java是实现这个算法的一种常用编程语言。下面...
本资源包含了一些图算法的Java实现,包括但不限于广度优先搜索(BFS)、深度优先搜索(DFS)、最小生成树(Minimum Spanning Tree, MST)、弗洛伊德算法(Floyd-Warshall)以及拓扑排序。下面将详细介绍这些算法及其...
对于给定的"本周算法图的拓扑排序Java开发Java经验技巧共6页.pdf.zip"文件,很可能是包含了一篇关于拓扑排序在Java编程实践中的详细教程或指南,内容可能包括理论解释、代码示例、常见问题以及优化技巧。通过阅读这...
拓扑排序是图论中的一个重要概念,特别是在有向无环图(DAG,Directed Acyclic Graph)中。在计算机科学中,它常被用于解决依赖关系的排序问题,例如任务调度、编译器的语句生成等。在这个“拓扑排序应用系统java....
另一方面,拓扑排序是将有向无环图(DAG)的顶点线性排列的一种方式,如果存在环,则无法进行拓扑排序,因此可以借此判断图中是否有环。 在`Graph.java`中,可能会有一个名为`detectCycle`的函数,它使用DFS进行...
1. **深度优先搜索(DFS)**或**广度优先搜索(BFS)**:这两种算法都可以用于实现拓扑排序。DFS通常会产生一个深浅不一的排序,而BFS则会得到一个较为均匀的排序结果。在排课场景中,BFS可能更为合适,因为它可以...
- 拓扑排序:在有向无环图(DAG)中,DFS可以用于拓扑排序,确定节点的顺序。 5. **代码示例**: 在Java中,使用递归实现二叉树的DFS遍历(前序、中序、后序)如下: ```java class TreeNode { int val; ...
在有环的有向图上执行拓扑排序是不定义的,因此程序应检测到环并给出适当的错误提示。 6. **可视化**:为了让用户直观看到拓扑排序的过程,可以使用动画效果,动态展示节点的移动和排序顺序。这需要在GUI中集成动画...
图的深度优先遍历和广度优先遍历是探索图结构的两种基本方法,它们各有优势。DFS适合查找路径或进行拓扑排序,而BFS则更适合寻找最短路径或检查连通性。在Java中,通过适当的递归或迭代算法结合数据结构(如栈或队列...
深度优先搜索(DFS,Depth-First Search)是图论与数据结构中的一种经典搜索算法,广泛应用于解决实际问题,如网络爬虫、迷宫求解、拓扑排序等。本课程“20180729数据结构与算法基础班深度优先搜索”将深入探讨这一...
本文将深入探讨Java中实现的四个核心图算法:深度优先遍历(DFS)、广度优先遍历(BFS)、最短路径算法以及最小生成树算法。 首先,**深度优先遍历(DFS)**是一种用于遍历或搜索树或图的算法。它从根节点开始,尽...
深度优先搜索(Depth-First Search, DFS)是一种用于遍历或搜索树或图的算法,它的基本思想是尽可能深地探索图的分支。在遇到死胡同时,算法会回溯到上一步,尝试其他可能的路径。DFS在解决许多算法问题中发挥着重要...
在IT领域,图遍历是数据结构和算法中一个重要的概念,主要应用于网络拓扑排序、搜索路径等问题。本文将详细讲解"Graph-DFS_WFS.zip"压缩包中涉及的知识点,包括Java实现的无向图、深度优先遍历(DFS)以及宽度优先...
3. **拓扑排序**:在有向无环图(DAG)中,DFS可以用来进行拓扑排序,将所有节点按照没有前驱的顺序排列。 4. **迷宫求解**:DFS也可以应用于二维数组表示的迷宫问题,从起点开始,不断尝试所有可能的路径,直到找到...
用Java描述的图,以邻接表存储,包含常用算法
拓扑排序是图论中的一个重要概念,特别是在有向无环图(DAG,Directed Acyclic Graph)中。在这个课程设计报告中,我们将深入探讨拓扑排序的原理、应用及其实现过程。 一、程序分析 1)输入需求:拓扑排序算法通常...
总的来说,Java中的深度优先搜索可以通过栈或递归来实现,用于遍历图或树结构的所有节点。理解并熟练掌握DFS对于解决许多图论问题至关重要,例如寻找连通分量、判断有向图是否存在环、求解最短路径等。在实际应用中...