import java.util.ArrayList; import java.util.LinkedList; import java.util.List; import java.util.Queue; /** * 该类演示拓扑排序的算法与实现 */ public class Main { public static List<Integer> topologicalSorting(int n, int[][] vertexMatrix) { // 创建一个用于输出拓扑排序结果的集合,入度为0的顶点会一次添加到此列表中 List<Integer> topoRes = new ArrayList<>(); // 1、首先是要创建一个数组对象,用于保存结点的入度 int[] inDegree = new int[n]; // 遍历所有所有子结点的,得到结点的入度并保存 for (int i = 0; i < vertexMatrix.length; i++) { int child = vertexMatrix[i][1]; inDegree[child]++; } // 创建一个队列,用于将入度为0的顶点放入其中 Queue<Integer> queue = new LinkedList<>(); for (int i = 0; i < n; i++) { if (inDegree[i] == 0) { queue.offer(i); } } // 从队列中取值 while (!queue.isEmpty()) { int curr = queue.poll(); // 取出 topoRes.add(curr); // 添加到输出结果中 // 循环遍历,找出父结点等于curr的结点,将他的子节点的入度减去1 // 因为已经从有向图中取出了父节点 for (int i = 0; i < vertexMatrix.length; i++) { int parent = vertexMatrix[i][0]; // 判断,如果父节点等于curr,则将其子节点的入度减去1 if (parent == curr) { int child = vertexMatrix[i][1]; inDegree[child]--; // 子节点的入度减去1之后,如果入度为0,则可以添加到队列 if (inDegree[child] == 0) { queue.offer(child); } } } } // 如果对有向图进行拓扑排序后,结果集合的大小小于节点数,说明该有向图不是“有向无环图” // 那么无法进行拓扑排序,返回空集合。 return topoRes.size() == n ? topoRes : new ArrayList<>(); } public static void main(String[] args) { // write your code here int n = 5; int[][] vertexMatrix = {{0, 1}, {0, 2}, {1, 2}, {1, 3}, {2, 3}, {4, 3}, {2, 4}}; System.out.println(topologicalSorting(n, vertexMatrix)); } }