拓撲排序的BFS做法

無論是 directed 還是 undirected Graph,其 BFS 的核心都在於 "indegree",處理順序也是從 indegree 最小的開始。

算法如下:

1) 先用一個 HashMap 統計下所有節點的 indegree; 

(值越高的,在拓撲排序中位置也就越靠後,因爲還有 N = current indegree 的 parent node 們沒有處理完。)

2) 因此在循環最開始,我們把所有 indegree = 0作爲(均不在 hashmap中) (1)BFS 的起點(進queue) (2)加到 list 中。

3) 在 BFS 過程中,我們依次取出隊列裏 node 的 neighbors,並把他們的 indegree減去1,代表其 parent node 已經被處理完,有效 indegree 減少。

4) 當減去1之後node 的 indegree 已經是 0 (1)BFS 的起點(進queue) (2)加到 list 中

public class Solution {
    /**
     * @param graph: A list of Directed graph node
     * @return: Any topological order for the given graph.
     */    
    public ArrayList<DirectedGraphNode> topSort(ArrayList<DirectedGraphNode> graph) {
        // write your code here
        ArrayList<DirectedGraphNode> list = new ArrayList<DirectedGraphNode>();


        // Key : node
        // Value : current in-degree count
        HashMap<DirectedGraphNode, Integer> map = new HashMap<>();
        for(DirectedGraphNode node : graph){
            for(DirectedGraphNode neighbor : node.neighbors){
                if(!map.containsKey(neighbor)){
                    map.put(neighbor, 1);
                } else {
                    map.put(neighbor, map.get(neighbor) + 1);
                }
            }
        }


        // Now we know each node's in-degree (out is trivial)
        Queue<DirectedGraphNode> queue = new LinkedList<>();


        Iterator<DirectedGraphNode> iter = graph.iterator();
        while(iter.hasNext()){
            DirectedGraphNode node = iter.next();
            // get all nodes without indegree
            if(!map.containsKey(node)){
                queue.offer(node);
                list.add(node);
            }
        }


        while(!queue.isEmpty()){
            DirectedGraphNode node = queue.poll();
            for(DirectedGraphNode next : node.neighbors){
                // node "next"'s parent has been processed
                map.put(next, map.get(next) - 1);
                if(map.get(next) == 0){
                    list.add(next);
                    queue.offer(next);
                } 
            }
        }


        return list;
    }
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章