原题地址:http://www.lintcode.com/zh-cn/problem/topological-sorting/
一.目的:给定一个有向图,对其进行点排序,即对于任何连接自顶点u到顶点v的有向边uv,在最后的排序结果中,顶点u总是在顶点v的前面。(该算法可以判断图中有无环)
二.思路:
1.根据点的入度来判定,在前面的肯定是入度为0的点,之后是为1为2等等。
2.将入度为0的点删除,则他们的邻居点全部入度减一,以此类推,当图中再无点后则排序结束。
在第二步中,具体的操作步骤如下
a.使用HashMap 保存节点和其入度。遍历入度大于0的点,即从邻居节点开始;
b.遍历图中所有点,如果不在HashMap中则说明入度为0,入队;
c.从队中poll节点,将其所有邻居节点入度减一,若等于0的入队,否则不管。
三.易错点:
这次难得一次通过一个题
public ArrayList<DirectedGraphNode> topSort(ArrayList<DirectedGraphNode> Graph){
ArrayList<DirectedGraphNode> result = new ArrayList<>();
HashMap<DirectedGraphNode,Integer> mapping = new HashMap<>();
//记录下所有有下一条指向的点并记录该被指的点的入度
for(DirectedGraphNode node : Graph){
for(DirectedGraphNode neighbor : node.neighbors){
if(mapping.containsKey(neighbor)){
mapping.put(neighbor, mapping.get(neighbor) + 1);
}else{
mapping.put(neighbor, 1);
}
}
}
Queue<DirectedGraphNode> queue = new LinkedList<>();
//将无来源点记录进queue和进result
for(DirectedGraphNode node : Graph){
if(!mapping.containsKey(node)){
queue.offer(node);
result.add(node);
}
}
//依次删除queue中的点,并将其邻居节点对应的mapping值减1,若为0则进queue和result,否则不管
while(!queue.isEmpty()){
DirectedGraphNode node = queue.poll();
for(DirectedGraphNode neighbor : node.neighbors){
mapping.put(neighbor, mapping.get(neighbor) - 1);
if(mapping.get(neighbor) == 0){
queue.offer(neighbor);
result.add(neighbor);
}
}
}
return result;
}