Topological Sorting

Given an directed graph, a topological order of the graph nodes is defined as follow:

  • For each directed edge A -> B in graph, A must before B in the order list.
  • The first node in the order can be any node in the graph with no nodes direct to it.

Find any topological order for the given graph.

http://www.lintcode.com/en/problem/topological-sorting/

Discussion


DFS + stack. 因为图可能不联通,所以不能从某一个node出发DFS,而应该从每一个没有被访问过的node出发。

Solution


/**
 * Definition for Directed graph.
 * struct DirectedGraphNode {
 *     int label;
 *     vector<DirectedGraphNode *> neighbors;
 *     DirectedGraphNode(int x) : label(x) {};
 * };
 */
class Solution {
public:
    /**
     * @param graph: A list of Directed graph node
     * @return: Any topological order for the given graph.
     */
    vector<DirectedGraphNode*> topSort(vector<DirectedGraphNode*> graph) {
        // write your code here
        vector<DirectedGraphNode*> result;
        int n = graph.size();
        if(n==0) return result;
        stack<DirectedGraphNode*> nodestk;
        unordered_map<DirectedGraphNode*, bool> isVisited;
        for(int i=0; i<n; i++) {
            if(isVisited.find(graph[i]) ==  isVisited.end()) {
               dfs(graph[i], isVisited, nodestk); 
            }
        }
        while(nodestk.empty() == false) {
            result.push_back(nodestk.top());
            nodestk.pop();
        }
        return result;
    }
    void dfs(DirectedGraphNode* curNode, 
    unordered_map<DirectedGraphNode*, bool> &isVisited, stack<DirectedGraphNode*> &stk) {
    //put node into the stack only after all its neighbors has been visited
        isVisited[curNode] = true;
        for(int i=0; i<curNode->neighbors.size(); i++) {
            if(isVisited.find(curNode->neighbors[i]) ==  isVisited.end()) {
                dfs(curNode->neighbors[i], isVisited, stk);
            }
        }
        stk.push(curNode);
    }
};

Iteration

void topSortHelper(DirectedGraphNode* node, unordered_set<DirectedGraphNode*> &is_visited,
    stack<DirectedGraphNode*> &stk) {
        stack<DirectedGraphNode*>  mystk;
        is_visited.emplace(node);
        mystk.emplace(node);
        while(!mystk.empty()) {
            DirectedGraphNode *cur = mystk.top();
            bool all = true;
            for(auto const & v: cur->neighbors) {
                if(is_visited.find(v) == is_visited.end()) {
                    mystk.emplace(v);
                    is_visited.emplace(v);
                    all = false;
                    break;//这里老是忘。。。
                }
            }
            if(all) {
                mystk.pop();
                stk.emplace(cur);
            }
        }
    }

Follow up

也可以通过计算indgree,BFS实现。

拓扑排序是假定图里面没有cycle的,关于如何判断图中是否存在cycle参考这篇文章

Reference

  1. http://www.geeksforgeeks.org/topological-sorting/
  2. http://www.geeksforgeeks.org/depth-first-traversal-for-a-graph/

results matching ""

    No results matching ""