import java.util.*;
/**
* 图的拓扑排序
* 1)从图中找到所有入度为0的点输出
* 2)把图中入度为0的点删掉,继续寻找入度为0的点输出,周而复始
* 3)图的所有节点被删除后,依次输出的顺序就是拓扑排序
* 要求:有向图且无环
* 应用:事件安排、编译顺序
*/
public class TopoSort {
// 图有向且无环
public static List<Node> sortedTopology(Graph graph) {
// key:某一个node
// value:剩余的入度
HashMap<Node, Integer> inMap = new HashMap<>();
// 剩余入度为0的点,才能进这个队列
Queue<Node> zeroInQueue = new LinkedList<>();
for (Node node : graph.nodes.values()) {
inMap.put(node, node.in);
if (node.in == 0) {
zeroInQueue.add(node);
}
}
// 拓扑排序的结果,依次加入result
List<Node> result = new ArrayList<>();
while (!zeroInQueue.isEmpty()) {
Node cur = zeroInQueue.poll();
result.add(cur);
for (Node next : cur.nexts) {
inMap.put(next, inMap.get(next) - 1);
if (inMap.get(next) == 0) {
zeroInQueue.add(next);
}
}
}
return result;
}
class Graph {
public HashMap<Integer, Node> nodes;
public HashSet<Edge> edges;
public Graph() {
nodes = new HashMap<>();
edges = new HashSet<>();
}
}
class Node {
public int value;
public int in;
public int out;
public ArrayList<Node> nexts;
public ArrayList<Edge> edges;
public Node(int value) {
this.value = value;
nexts = new ArrayList<>();
edges = new ArrayList<>();
}
}
class Edge {
// 权重
public int weight;
public Node from;
public Node to;
public Edge(int weight, Node from, Node to) {
this.weight = weight;
this.from = from;
this.to = to;
}
}
}
/* 如有意见或建议,欢迎评论区留言;如发现代码有误,欢迎批评指正 */