拓扑排序是一个数据结构,是一个有向图。
思路:首先我们要构造一个有向图,构造有向图的同时记录一下入度的长度。
构造完图之后,使用深度优先遍历去执行出度,当边的长度为0 的时候,就可以出度了。
代码如下
/**
* @author xnl
* @Description:
* @date: 2022/6/2 21:45
*/
import org.omg.PortableInterceptor.INACTIVE;
import java.util.*;
/**
* @author xienl
* @description
* @date 2022/6/2
*/
public class Solution {
public static void main(String[] args) {
Solution solution = new Solution();
System.out.println(solution.topology());
}
StringBuffer sb = new StringBuffer();
/**
* 拓扑排序
* @return
*/
private String topology() {
Scanner scanner = new Scanner(System.in);
String str = scanner.nextLine();
String[] split = str.split("\\s+");
int n = Integer.parseInt(split[0]);
int m = Integer.parseInt(split[1]);
// 所有的点
int[] inDegrees = new int[n];
// 初始化边
List<List<Integer>> edges = new ArrayList<>();
for (int i = 0; i < n; i++){
edges.add(new ArrayList<>());
}
for (int i = 0; i < m; i++){
String[] temp = scanner.nextLine().split("\\s+");
int left = Integer.parseInt(temp[0]);
int right = Integer.parseInt(temp[1]);
// z左边的边的下一个点加到左边点的图中
edges.get(left - 1).add(right - 1);
// 边加一
inDegrees[right - 1]++;
}
return bfs(edges, inDegrees) ? sb.toString().substring(0, sb.length() - 1) : "-1";
}
private boolean bfs(List<List<Integer>> edges, int[] inDegrees){
int num = 0;
Deque<Integer> deque = new LinkedList<>();
// 找出所有没有边的点
for (int i = 0; i < inDegrees.length; i++){
if (inDegrees[i] == 0){
deque.offer(i);
}
}
while (!deque.isEmpty()){
Integer poll = deque.poll();
sb.append((poll + 1) + " ");
for (int i = 0; i < edges.get(poll).size(); i++){
Integer temp = edges.get(poll).get(i);
// 边减一
inDegrees[temp]--;
if (inDegrees[temp] == 0){
deque.offer(temp);
}
}
num++;
}
return num == inDegrees.length;
}
}