拓扑排序思路:找到入度为0的节点,然后擦去该点对其他点的影响,然后再找到下一个入度为0的节点。
实现思路:
1.准备一个哈希表记录节点和该点剩余的入度,准备一个队列记录入度为0的点。
2.第一次遍历把所以节点的入度加到哈希表中,顺便找到第一批入度为0的点
3.准备一个list,把所以入度为0的(从队列中取出)节点加入其中。
4.遍历该入度为0的节点,擦掉他对后面节点的影响(让入度为0的邻居节点入度减1),如果入度减到0了就加入到队列中
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.Stack;
public class TopologySort{
public static class Graph{
public HashMap<Integer,Node> nodes;
public HashSet<Edge> edges;
public Graph(){
nodes = new HashMap<>();
edges = new HashSet<>();
}
}
public static 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;
in = 0;
out = 0;
nexts = new ArrayList<>();
edges = new ArrayList<>();
}
}
public static 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;
}
}
public static List<Node> SortedTopo(Graph graph){
//key记录节点,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);
}
}
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(next.in == 0){
zeroInQueue.add(next);
}
}
}
return result;
}
}