有向图的拓扑排序算法(java实现)
由AOV网构造拓扑序列的拓扑排序算法主要是循环执行以下两步,直到不存在入度为0的顶点为止。
(1) 选择一个入度为0的顶点并输出之;
(2) 从网中删除此顶点及所有出边。
循环结束后,若输出的顶点数小于网中的顶点数,则输出“有回路”信息,否则输出的顶点序列就是一种拓扑序列。
拓扑排序的应用场景很好理解,比如在内存中运行着很多任务,某个任务A的执行依赖于另外一个任务B,那么在A执行完之前,B一定不能被清理。而另外一些任务是没有关联的,如何来安排这些任务被清理的顺序就需要依赖拓扑排序。
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
public class TopologicalOrder{
static class Node{
int pos;
int val;
Node next;
}
static int n ,m;
static int N = 100010;
static Node[] h = new Node[N];
//每个节点的入度
static int [] d = new int[N];
//答案数组
static int [] ans = new int[N];
//p插入u为头节点邻接表
static void insert(int u,int p){
Node hh = h[u];
Node newNode = new Node();newNode.pos = p;newNode.next = hh.next;
hh.next = newNode;
}
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String [] s =in.nextLine().split(" ");
n = Integer.parseInt(s[0]);
m = Integer.parseInt(s[1]);
//初始化n个顶点
for(int i=1;i<=n;i++) {Node n = new Node();n.pos = i;h[i] = n;}
for(int i=1;i<=m;i++){
String [] ss = in.nextLine().split(" ");
int x = Integer.parseInt(ss[0]);
int y = Integer.parseInt(ss[1]);
insert(x,y);
//统计入读
d[y]++;
}
search();
}
static void search() {
Queue<Integer> q = new LinkedList<Integer>();
//队列中初始化入读为零的点
for(int i=1;i<=n;i++){
if(d[i]==0) q.add(i);
}
int size = 0;
while(!q.isEmpty()){
int p = q.poll();
//输出
ans[size++] = p;
while(h[p].next!=null){
Node f = h[p].next;
h[p].next = f.next;
int fp = f.pos;
if(--d[fp]==0) q.add(fp);
}
}
if(size == n) for(int i=0;i<n;i++) System.out.print(ans[i]+" ");
else System.out.println(-1);
}
}
https://www.cnblogs.com/bigsai/p/11489260.html 详细了解拓扑排序算法戳这儿
算法:
- 实现算法运用了邻接表
- 通过入度的是否为零判断能否加入队列中
主要流程:
- 把所有入度为0的节点添加到队列中
- 如果队列不为空
1.取队首元素 h 输出元素
2.遍历该元素的所有边 h->j
3.使j节点的入读减1
如果j的入度为0 把j加入到队列中
输出的顺序即为拓扑顺序