zoukankan      html  css  js  c++  java
  • Lintcode: 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.
    Note
    You can assume that there is at least one topological order in the graph.
    
    Example
    For graph as follow: 
    图片
    
    The topological order can be:
    
    [0, 1, 2, 3, 4, 5]
    
    or
    
    [0, 2, 3, 1, 5, 4]
    
    or
    
    ....
    
    
    
    Challenge
    Can you do it in both BFS and DFS?

    这道题参考了网上一些很好的思路:

    method1:  Record the pre nodes of every node, then find out a node without pre node in each iteration and delete this node from unvisited set, add this node to result.

     1 /**
     2  * Definition for Directed graph.
     3  * class DirectedGraphNode {
     4  *     int label;
     5  *     ArrayList<DirectedGraphNode> neighbors;
     6  *     DirectedGraphNode(int x) { label = x; neighbors = new ArrayList<DirectedGraphNode>(); }
     7  * };
     8  */
     9 public class Solution {
    10     /**
    11      * @param graph: A list of Directed graph node
    12      * @return: Any topological order for the given graph.
    13      */    
    14     public ArrayList<DirectedGraphNode> topSort(ArrayList<DirectedGraphNode> graph) {
    15         // write your code here
    16         ArrayList<DirectedGraphNode> res = new ArrayList<DirectedGraphNode>();
    17         if (graph.size() == 0) return res;
    18         HashMap<DirectedGraphNode, Set<DirectedGraphNode>> map = new HashMap<DirectedGraphNode, Set<DirectedGraphNode>>();
    19         for (DirectedGraphNode each : graph) {
    20             map.put(each, new HashSet<DirectedGraphNode>());
    21         }
    22         for (DirectedGraphNode each : graph) {
    23             for (int i=0; i<each.neighbors.size(); i++) {
    24                 map.get(each.neighbors.get(i)).add(each);
    25             }
    26         }
    27         while (graph.size() > 0) {
    28             int index = 0;
    29             while (index < graph.size()) {
    30                 DirectedGraphNode cur = graph.get(index);
    31                 if (map.get(cur).size() == 0) {
    32                     //add the node to our result
    33                     //remove the node from the graph
    34                     res.add(cur);
    35                     graph.remove(index);
    36                     for (DirectedGraphNode elem : graph) {
    37                         if (map.get(elem).contains(cur)) {
    38                             map.get(elem).remove(cur);
    39                         }
    40                     }
    41                 }
    42                 else index++;
    43             }
    44         }
    45         return res;
    46     }
    47 }

    method2: DFS: use a recursive method, randomly pick up an unmakred node, before adding it into result list, recursively visite all its neighbors and add its neighbors into list first. In this way, we guarantee that all the nodes belong to some node's post nodes will be added to the result list first.

    To be more specific, we can modify DFS to find Topological Sorting of a graph. In DFS, we start from a vertex, we first print it and then recursively call DFS for its adjacent vertices. In topological sorting, we don’t print the vertex immediately, we first recursively call topological sorting for all its adjacent vertices, then print the current vertex. In this way, we ensure a node's neighbor nodes are always added before the node itself.

     1 /**
     2  * Definition for Directed graph.
     3  * class DirectedGraphNode {
     4  *     int label;
     5  *     ArrayList<DirectedGraphNode> neighbors;
     6  *     DirectedGraphNode(int x) { label = x; neighbors = new ArrayList<DirectedGraphNode>(); }
     7  * };
     8  */
     9 public class Solution {
    10     /**
    11      * @param graph: A list of Directed graph node
    12      * @return: Any topological order for the given graph.
    13      */    
    14     public ArrayList<DirectedGraphNode> topSort(ArrayList<DirectedGraphNode> graph) {
    15         // write your code here
    16         ArrayList<DirectedGraphNode> res= new ArrayList<DirectedGraphNode>();
    17         if (graph.size() == 0) return res;
    18         HashMap<DirectedGraphNode, Integer> status = new HashMap<DirectedGraphNode, Integer>();
    19         for (DirectedGraphNode elem : graph) {
    20             status.put(elem, 0);
    21         }
    22         ArrayList<DirectedGraphNode> templist = new ArrayList<DirectedGraphNode>();
    23         templist.add(null);
    24         while (hasUnvisited(graph, status, templist)) {
    25             DirectedGraphNode cur = templist.get(0);
    26             templist.set(0, null);
    27             search(cur, status, res);
    28         }
    29         return res;
    30     }
    31     
    32     public boolean hasUnvisited(ArrayList<DirectedGraphNode> graph, HashMap<DirectedGraphNode, Integer> status, ArrayList<DirectedGraphNode> templist) {
    33         for (DirectedGraphNode elem : graph) {
    34             if (status.get(elem) == 0) {
    35                 templist.set(0, elem);
    36                 return true;
    37             }
    38         }
    39         return false;
    40     }
    41     
    42     public void search(DirectedGraphNode cur, HashMap<DirectedGraphNode, Integer> status, ArrayList<DirectedGraphNode> res) {
    43         if (status.get(cur) == 1) System.out.println("not a DAG");
    44         if (status.get(cur) == 2) return;
    45         status.put(cur, 1);
    46         for (DirectedGraphNode neigh : cur.neighbors) {
    47             search(neigh, status, res);
    48         }
    49         status.put(cur, 2);
    50         res.add(0, cur);
    51     }
    52 }
  • 相关阅读:
    [script]判定dd是否成功
    [script]判定某一个脚本是否正确执行
    [wifi]wifi模块的测试
    [其他]设计开发
    [应用]Linux下" >/dev/null 2>&1 "
    [log]利用logrotate对Linux log进行管理
    [sz,rz]使用sz/rz在两台Linux设备之间传输数据
    [Kernel]内核版本添加字符和内核版本'+'解决
    [Linux应用]Linux应用程序输出数据重定向到文件中
    [systemd]How To Use Systemctl to Manage Systemd Services and Units
  • 原文地址:https://www.cnblogs.com/EdwardLiu/p/4431722.html
Copyright © 2011-2022 走看看