`
shenyu
  • 浏览: 122960 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

图-拓扑排序

阅读更多

当每个任务有前后置关系时,需要找到一种满足前后置关系的路线,将任务完成。

如果将每个任务看成一个节点,任务之间的前后置关系表示为有向图时,这种路线顺序叫做为图进行拓扑排序。也叫关键路径分析。

这里的图用邻接矩阵法表示,算法的关键是:

1 找到一个没有后继的顶点

2 在图中删除它,放入结果数组中

3 重复 步骤 1 ,步骤 2 直到图中没有多余的节点。

如果图中出现环装结构,则算法无法进行,因为此时任务之间循环成为前置。

关于邻接矩阵法请参见:Graph 图-邻接表法。

要注意的是:满足前后置关系的路径可能不止一条。这里仅仅得到其中的一条。

关键API:

   int noNext():返回没有后继的节点的下标。

   remove(int index):删除指定下标的节点,同时在邻接矩阵中删除相对应的行与列。

   main:提供简单的测试。

代码如下:

class Vertex {	//图中的节点
	private Object value;
	Vertex(Object value) {
		this.value = value;
	}
	Object value() { return value; }
	@Override public String toString() { return "" + value; }
}

class Topology {	//用邻接矩阵法表示的图
	private Vertex[] vertexs;
	private Object[][] adjMat;	//记载是否联通	
	private int length = 0;
	private static Object CONN = new Object();	//标致是否联通

	Topology(int size) {
		vertexs = new Vertex[size];
		adjMat = new Object[size][size];
	}

	void add(Object value) {
		assert length <= vertexs.length;
		vertexs[length++] = new Vertex(value);
	}

	void connect(int from, int to) {
		assert from < length;
		assert to < length;
		adjMat[from][to] = CONN;	//标志联通
	}

	void remove(int index) {	//移除指定的顶点
		remove(vertexs,index);	//在顶点数组中删除指定位置的下标
		for(Object[] bs: adjMat) remove(bs,index);	//邻接矩阵中删除指定的列
		remove(adjMat,index);	//在邻接矩阵中删除指定的行
		length--;
	}

	private void remove(Object[] a, int index) {	//在数组中移除指定的元素,后面的元素补上空位
		for(int i=index; i<length-1; i++) a[i] = a[i+1];
	}

	int noNext() {	//寻找没有后继的节点
		int result = -1;
OUT:
		for(int i=0; i<length; i++) {
			for(int j=0; j<length; j++) {
				if(adjMat[i][j] == CONN)continue OUT;	//如果有后继则从外循环继续寻找
			}
			return i;	//如果没有与任何节点相连,则返回该节点下标
		}
		return -1;	//否则返回-1
	}

	Object[] topo() {
		Object[] result = new Object[length];	//准备结果数组
		int index;
		int pos = length;
		while(length > 0) {
			index = noNext();	//找到第一个没有后继的节点	
			assert index != -1 : "图中存在环";
			result[--pos] = vertexs[index]; //放入结果中
			remove(index);	//从图中把它删除
		}
		return result;
	}

	public static void main(String[] args) {
		Topology g = new Topology(20);
		g.add('a');
		g.add('b');
		g.add('c');
		g.add('d');
		g.add('e');
		g.add('f');
		g.add('g');
		g.add('h');

		g.connect(0,3);
		g.connect(0,4);
		g.connect(1,4);
		g.connect(2,5);
		g.connect(3,6);
		g.connect(4,6);
		g.connect(5,7);
		g.connect(6,7);

		for(Object o: g.topo()) System.out.print(o + " ");
		System.out.println();
	}
}
 
2
0
分享到:
评论
3 楼 lixia0417 2010-07-13  
楼主,这个remove用得巧妙,我一般都写三个remove才搞定的;
2 楼 fuliang 2008-08-26  
这个算法效率太低了。
1 楼 run_xiao 2008-08-06  
拓扑排序的另一个解法:可以利用深度遍历,递归地在遍历完每个节点的后继节点后,打印出该节点

相关推荐

    startup-拓扑排序

    拓扑排序 拓扑排序 拓扑排序 拓扑排序 拓扑排序

    data-structure-and-algorithm-拓扑排序

    拓扑排序 拓扑排序 拓扑排序 拓扑排序 拓扑排序

    DataStructure-拓扑排序

    Swift 拓扑排序 拓扑排序 拓扑排序 拓扑排序 拓扑排序

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

    数据结构课程的课程设计,实现拓扑排序的算法

    图-Floyed算法-Dijkstra算法-拓扑排序算法(VC++程序)

    这里我们主要探讨三种经典的图算法:Floyd算法、Dijkstra算法和拓扑排序算法。 1. **Floyd算法**,也称为Floyd-Warshall算法,是一种解决所有顶点对之间最短路径问题的动态规划方法。它通过考虑所有的中间节点,...

    blog-拓扑排序blog-拓扑排序

    :dart: 拓扑排序 拓扑排序 拓扑排序 拓扑排序 拓扑排序

    数据结构与算法分析课程设计--拓扑排序

    在本课程设计中,我们聚焦于一个特定的应用——"拓扑排序",这是一种用于有向无环图(DAG, Directed Acyclic Graph)的排序方法,尤其适用于规划和安排任务或课程的优先级。 拓扑排序是将DAG中的所有节点排列成线性...

    数据结构-拓扑排序.ppt

    数据结构中的拓扑排序是一种对有向无环图(DAG, Directed Acyclic Graph)进行线性排列的方法,它确保了如果在图中存在从顶点A到顶点B的路径,那么在排序后的序列中,顶点A必定出现在顶点B之前。这种排序对于解决...

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

    非常好的源程序文件,用vc++6.0编写的拓扑排序 程序简单易懂,问题描述完善 非常有用

    有向图的拓扑排序

    对于有向图进行拓扑排序,图使用邻接矩阵的存储结构。

    简单拓扑排序——源码

    拓扑排序是图论中的一个重要概念,主要应用于有向无环图(DAG,Directed Acyclic Graph)。在这样的图中,节点之间的关系是有方向性的,而拓扑排序就是找到一个线性的顺序,使得对于每一条边 (u, v),节点 u 都在这...

    拓扑排序的演示

    拓扑排序是图论中的一个重要概念,特别是在有向无环图(DAG,Directed Acyclic Graph)中。在这个课程设计中,我们很可能涉及到如何通过编程实现拓扑排序的方法,这通常用于解决任务调度、依赖关系排序等问题。让...

    拓扑排序-数据结构-图

    图的拓扑排序是数据结构领域中图论的一部分,它主要应用于有向无环图(DAG,Directed Acyclic Graph)。在这样的图中,拓扑排序是对所有节点的一种线性排列,使得对于每一条有向边 (u, v),节点 u 在排列中都出现在...

    数据结构拓扑排序课程设计.docx

    【拓扑排序】是图论中的一个重要概念,用于对有向无环图(DAG,Directed Acyclic Graph)进行线性排序。在这个过程中,我们尝试按照一定的顺序排列顶点,使得对于图中的每一条有向边 (u, v),顶点 u 总是出现在顶点 ...

    拓扑排序------打印输出计算机本科专业4年每学期的课表

    拓扑排序是图论中的一个重要概念,特别是在有向无环图(DAG,Directed Acyclic Graph)中。在这个场景中,计算机本科专业的四年课程安排可以被看作是一个有向图,其中每个节点代表一门课程,箭头则表示课程之间的先...

    递归拓扑排序-非递归拓扑排序 Python

    有向无环图 (DAG) 的拓扑排序是顶点的线性排序,因此对于每个有向边 uv,顶点 u 在排序中排在 v 之前。如果图形不是 DAG,则无法对图形进行拓扑排序。 2、非递归拓扑排序 Python 解决拓扑排序的方法是在处理完节点...

    拓扑排序 整体 拓扑排序

    拓扑排序是图论中的一个重要概念,主要应用于有向无环图(DAG,Directed Acyclic Graph)。在计算机科学中,特别是在数据结构和算法领域,拓扑排序常常用于解决依赖关系的排序问题,例如课程安排、任务调度等场景。...

    图的最短路径、拓扑排序和关键路径

    "图的最短路径、拓扑排序和关键路径" 图的最短路径是图论中的一种重要概念,它是指从图的一顶点到另一顶点的路径中,所经过的边的数目最少的那条路径。这种路径也可以称作最短距离或最短路径长度。在无权图中,图的...

    c语言实现图的拓扑排序

    拓扑排序是对有向无环图(DAG,Directed Acyclic Graph)的一种线性排序,它使得对于图中的每一条有向边 (u, v),节点 u 的排序位置总是在节点 v 之前。在实际应用中,例如课程安排、项目依赖关系解决等场景,拓扑...

    图的拓扑排序和有向无环图的判断

    图的拓扑排序和有向无环图(Directed Acyclic Graph, DAG)的判断是图论中的基础概念,广泛应用于计算机科学的多个领域,如任务调度、编译器设计等。拓扑排序是对有向无环图进行线性排列的一种方式,而DAG的环检测则...

Global site tag (gtag.js) - Google Analytics