拓扑排序
一个顶点活动网(AOV网)是一个有向无环图
正常情况下,通过拓扑排序,按照拓扑序列(不是唯一的)进行执行,所有的活动都能够被完成
但是,如果图中有环,则有一部分活动不能被正常完成(相当于形成了一个循环依赖,没有一个点的入读能够变为0,那这些点对应的活动都不能被执行)
图可以通过邻接表进行存储
img解决拓扑排序问题使用到的数据结构稍有不同
Vertex{
Int 入度;
char 数据
Edge 第一条出边
}
Edge{
//Int weight权重
Vertex 指向的顶点
Edge 下一条出边
}
构造这样的数据:
- 首先有n个有编号的有序事件,为每个事件创建一个Vertex,data数据域存放编号,将这些Vertex 按序 存放到List<Vertex>中
- 遍历依赖关系,根据每个依赖关系建立Edge 如任务2依赖任务1和任务0:则建立两条边,分别指向Vertex0和Vertex1,第一条边的Edge为第二条边,第二条边的Edge为null,在这个过程中,要同时更新指向的Vertex的入度;然后将Vertex2的Edge指向第一条边
得到一个List<Vertex>,其中包含了顶点信息和边的信息
下面通过这个数据进行处理:
- Int outputVertices=0;记录输出的顶点的个数,如果最终输出的顶点的个数和List的长度相同,也就是输出了所有的顶点,完成了所有的任务,则这个图是正常的AOV,是没有环的
- Stack<Vertex> stack=new Stack<>();
将所有入读为0的顶点入栈,这些任务是现在可以进行输出的(也就是可以完成的,因为它们的前置任务都已经完成了)
- for (Vertex vertex : graph) { if (vertex. inNumber O) { stack. push (vertex);
- 每次拿出一个顶点,要对该顶点的所有出边进行处理,如果处理过程中有新的入读为0的顶点要进行压栈
循环,直到栈为空,此时没有可以完成的任务
- 判断
- if true. (outvertices graph.size()){ return true;
在顶点不需要存储具体的数据、边不存在权重的情况下,可以使用更加简单的数据结构
两个数组就可以解决:
深入理解拓扑排序(Topological sort) - 简书 (jianshu.com)
关于上面的截图中二维数组的使用:
image-20230415155210515这样是可以的,或者用arrayList,只要构造成一种二维表的形式就可以
网友评论