`

java 图论二 有向图 拓扑排序

阅读更多

有向图的拓扑排序,能够获得访问到某一节点的提前条件。

拓扑排序时不可以实现环和图的拓扑排序。

 

写一下拓扑排序的实现:

是在联通矩阵上实现的,拓扑排序的算法是:

1.查看连通矩阵是否还有剩余节点,如果有继续2,3操作,如果没有结束拓扑排序

2.找到没有后继的节点

3.如果找到了,从联通矩阵中删除;如果没找到,则此联通矩阵不是DAG,不能进行拓扑排序

package com.Construction;

import java.util.LinkedList;
import java.util.Queue;
import java.util.Stack;

public class GraphSimpleExample {
	private final int MAX_VERTS = 20;
	private GraphNodeBean nodeList[];
	private int adjMat[][];
	private int nVerts;
	
	public GraphSimpleExample(){
		nodeList = new GraphNodeBean[MAX_VERTS];
		adjMat = new int[MAX_VERTS][MAX_VERTS];
		nVerts = 0;
		for (int i = 0; i < MAX_VERTS; i++) {
			for (int j = 0; j < MAX_VERTS; j++) {
				adjMat[i][j] = 0;
			}
		}
	}
	
	public void addNode(char label){
		nodeList[nVerts++] = new GraphNodeBean(label);
	}
	
	public void addEdge(int start,int end){
		adjMat[start][end] = 1;
		adjMat[end][start] = 1;
	}

	public void displayGraphNode(int v){
		System.out.println(nodeList[v].label);
	}
	
	/**
	 * 获得未访问节点
	 * @param v
	 * @return
	 */
	public int getAdjUnvisitedVertex(int v){
		for (int i = 0; i < nVerts; i++) {
			if(adjMat[v][i]==1 && nodeList[i].isVisited == false)
				return i;
		}
		return -1;
	}
	
	/**
	 * deft first 
	 */
	public void dfs(){
		@SuppressWarnings("rawtypes")
		Stack<Integer> theStack = new Stack<Integer>();
		nodeList[0].isVisited = true;
		displayGraphNode(0);
		theStack.push(0);
		
		while(!theStack.isEmpty()){
			int v = getAdjUnvisitedVertex(theStack.peek());
			if(v == -1)
				theStack.pop();
			else{
				nodeList[v].isVisited = true;
				displayGraphNode(v);
				theStack.push(v);
			}
		}
//		for (int i = 0; i < nVerts; i++) {
//			nodeList[i].isVisited = false;
//		}
	}
	
	public void bds(){
		Queue<Integer> theQueue = new LinkedList<Integer>();
		
		nodeList[0].isVisited = true;
		displayGraphNode(0);
		theQueue.offer(0);
		int v2;
		
		while(!theQueue.isEmpty()){
			int v1 = theQueue.poll();
			while((v2 = getAdjUnvisitedVertex(v1)) != -1){
				nodeList[v2].isVisited = true;
				displayGraphNode(v2);
				theQueue.add(v2);
			}
		}
//		for (int i = 0; i < nVerts; i++) {
//		nodeList[i].isVisited = false;
//	}
		
	}
	
	
	
	/**
	 * topologically output all the node 简单的拓扑排序
	 * 找到无后续节点,并输出,直到没有节点位置。
	 * 可以输出所有有顺序的关系,但是正确的输出不是唯一滴
	 * note: the graph only be DAG - including 不连通树, can't has cycles 环合树
	 */
	public void topo(){
		int orig_nVerts = nVerts;
		GraphNodeBean[] sortedArray = new GraphNodeBean[nVerts];
		
		while(nVerts > 0){
			int currentVertex = noSuccessor();
			if(currentVertex == -1){
				System.out.println("Error : Graph has cycles");
				return;
			}
			sortedArray[nVerts - 1] = nodeList[currentVertex];
			deleteVertex(currentVertex);
		}
		System.out.println("TOPOlogically sorted order:");
		for (int i = 0; i < orig_nVerts; i++) {
			System.out.println(sortedArray[i].label);
		}
	}
	
	/**
	 * within topology graph add a edge
	 * @param start
	 * @param end
	 */
	public void addTopoEdge(int start,int end){
		adjMat[start][end] = 1;
	}
	
	/**
	 * 找到没有后继的节点
	 * @return
	 */
	public int noSuccessor(){
		boolean isEdge;
		for (int i = 0; i < nVerts; i++) {
			isEdge = false;
			for (int j = 0; j < nVerts; j++) {
				if(adjMat[i][j] > 0){
					isEdge = true;
					break;
				}
			}
			if(!isEdge)
				return i;
		}
		return -1;
	}
	
	/**
	 * delete certain node on the graph
	 * @param delVert
	 */
	public void deleteVertex(int delVert){
		if(delVert != nVerts - 1){
			movingVertexData(delVert);
			for (int i = delVert; i < nVerts; i++) 
				this.moveRowUp(i, nVerts);
			for (int i = delVert; i < nVerts; i++) 
				this.moveColLeft(i, nVerts-1);
		}
		nVerts --;
	}
	
	/**
	 * delete data from graph
	 * @param index the number of data start with 0
	 */
	public void movingVertexData(int index){
		for (int i = index; i < nVerts -1; i++) {
			nodeList[i] = nodeList[i+1];
		}
	}
	
	/**
	 * row move up
	 * @param row  moving row number that start with 0
	 * @param length  table column length
	 */
	public void moveRowUp(int row,int length){
		for (int i = 0; i < length; i++) {
			adjMat[row][i] = adjMat[row+1][i];
		}
	}
	
	/**
	 * col move left
	 * @param col  moving column number that start with 0
	 * @param length table row lenglth;
	 */
	public void moveColLeft(int col,int length){
		for (int i = 0; i < length; i++) {
			adjMat[i][col] = adjMat[i][col+1];
		}
	}
	
	
	
}
 
分享到:
评论
1 楼 hyde12 2013-04-09  
      

相关推荐

    Java版查找并打印有向图中的所有环路径

    在标题中提到的"Java版查找并打印有向图中的所有环路径",这个问题涉及到图论中的一个经典问题——寻找环路。在实际应用中,如线程死锁识别,有向图的环路检测具有重要价值,因为线程间的资源依赖关系可以被抽象为有...

    拓扑排序java语言

    拓扑排序是图论中的一个重要概念,主要用于有向无环图(DAG,Directed Acyclic Graph)。在计算机科学中,特别是在数据结构和算法领域,拓扑排序常常用于解决任务调度、依赖关系分析等问题。Java语言提供了强大的...

    JAVA拓扑排序实现及分析

    在计算机科学中,拓扑排序是对有向无环图(DAG,Directed Acyclic Graph)进行排序的一种方法,它将图中的所有节点排列成一个线性的序列,且满足这样的条件:如果有从节点u到节点v的有向边,那么在排序结果中u必须...

    本周算法图的拓扑排序Java开发Java经验技巧共6页.p

    拓扑排序是处理有向无环图(DAG,Directed Acyclic Graph)的一种基本方法,它对于理解和解决许多实际问题有着广泛的应用,如任务调度、依赖分析等。在Java开发中,理解并能熟练应用拓扑排序可以显著提高代码效率和...

    拓扑排序应用系统java.zip

    拓扑排序是图论中的一个重要概念,特别是在有向无环图(DAG,Directed Acyclic Graph)中。在计算机科学中,它常被用于解决依赖关系的排序问题,例如任务调度、编译器的语句生成等。在这个“拓扑排序应用系统java....

    [宫水三叶的刷题日记]:(图论)拓扑排序1

    总结来说,拓扑排序是解决有向图中寻找特定属性节点(如安全节点)的有效工具。通过广度优先搜索,我们可以确保在有限步骤内遍历所有可达节点,并按照特定规则(如升序)生成排序结果。在实际编程中,使用Java或其他...

    深度优先搜索输出有向图中的所有环(JAVA)

    总之,深度优先搜索是图论中的基础算法之一,通过DFS寻找有向图中的环是解决图问题的一个典型应用。在Java编程中,我们可以利用邻接表和栈来实现这个功能。通过分析`TestCycle.java`文件,我们可以深入理解这一过程...

    数据结构拓扑排序图形化界面实现

    在有环的有向图上执行拓扑排序是不定义的,因此程序应检测到环并给出适当的错误提示。 6. **可视化**:为了让用户直观看到拓扑排序的过程,可以使用动画效果,动态展示节点的移动和排序顺序。这需要在GUI中集成动画...

    数据结构拓扑排序课程设计报告

    数据结构中的拓扑排序是一种对有向无环图(DAG)进行线性排序的方法,使得如果图中存在边, v&gt;,则u在排序结果中一定在v之前。这个概念在解决依赖关系的问题中非常有用,例如任务调度或课程安排等。拓扑排序的目标是...

    图的几种常用算法(广度/深度优先搜索,最小生成树,弗洛伊德,拓扑排序....)java实现,简单易懂。

    拓扑排序是对有向无环图(DAG)的线性排序,使得对于每条有向边 (u, v),节点u总是在节点v之前。Java实现中,可以使用队列配合深度优先搜索来完成拓扑排序,或者使用栈配合反向深度优先搜索。 这些算法的Java实现...

    Putuo-Sort.rar_拓扑排序

    拓扑排序是图论中的一个重要概念,特别是在有向无环图(DAG,Directed Acyclic Graph)中。在这个课程设计报告中,我们将深入探讨拓扑排序的原理、应用及其实现过程。 一、程序分析 1)输入需求:拓扑排序算法通常...

    Java编写的课表排序

    拓扑排序是图论中的一个概念,主要用于有向无环图(DAG,Directed Acyclic Graph)。在课表安排场景中,每个课程可以视为图中的一个节点,如果课程A必须在课程B之前完成,那么就有一条从A到B的有向边。拓扑排序就是...

    拓扑序列的演示

    拓扑排序是图论中的一个重要概念,特别是在有向无环图(DAG,Directed Acyclic Graph)中。在这个数据结构的资源中,你将能够动态地观察和理解拓扑排序的过程。拓扑排序是对有向无环图的顶点的一种线性排序,使得...

    java实现带权无环图关键路径查找

    2. **拓扑排序**:由于是无环图,我们可以对其进行拓扑排序,得到一个节点的线性顺序,使得对于每一条有向边 `(u, v)`,节点 `u` 在节点 `v` 之前。 3. **计算节点的最早开始时间和最晚开始时间**:遍历拓扑排序后...

    图论算法与程序设计

    1. **图的基本概念**:图由顶点(Vertex)和边(Edge)组成,可以是无向图或有向图,边可以有权重(Weighted)或无权重。图的数据结构通常用邻接矩阵或邻接表来表示。 2. **遍历算法**:深度优先搜索(DFS)和广度...

    图论算法及其matlab程序代码.pdf

    6. **拓扑排序**:对于有向无环图(DAG),可以使用拓扑排序来排列顶点,使得对于每条有向边,其起点都在终点之前。 7. **最大流最小割问题**:Ford-Fulkerson算法或Edmonds-Karp算法用于解决网络流问题,找到网络...

    GraphsAndStuff:用于图论操作的Java API

    1. **图类**:API的核心是一个代表图的类,可能名为`Graph`或`UndirectedGraph`(无向图)和`DirectedGraph`(有向图)。此类通常包含顶点和边的集合,以及添加、删除和查询这些元素的方法。 2. **顶点类**:API会...

    算法 图论 查询文件

    图的类型包括有向图、无向图、加权图和树等,每种都有其特定的应用场景。 1. **图的表示**:在Java中,我们可以用邻接矩阵或邻接表来表示图。邻接矩阵是一个二维数组,其中的元素表示顶点之间的连接;邻接表则更...

Global site tag (gtag.js) - Google Analytics