| 1 | // https://en.wikipedia.org/wiki/Topological_sorting |
| 2 | // A DFS RECURSIVE ALGORITHM .... |
| 3 | // An alternative algorithm for topological sorting is based on depth-first search. The algorithm loops through each node of the graph, in an arbitrary order, initiating a depth-first search that terminates when it hits any node that has already been visited since the beginning |
| 4 | // of the topological sort or the node has no outgoing edges (i.e. a leaf node) |
| 5 | // Discussion: https://www.gatevidyalay.com/topological-sort-topological-sorting/ |
| 6 | // $ v run dfs_topological_ordering.v |
| 7 | // Author: CCS |
| 8 | |
| 9 | // THE DFS RECURSIVE .... classical searchig for leaves nodes |
| 10 | // the arguments are used in the function to avoid global variables.... |
| 11 | fn dfs_recursive(u string, mut visited map[string]bool, graph map[string][]string, mut top_sorting []string) { |
| 12 | print(' Visiting: ${u} -> ') |
| 13 | visited[u] = true |
| 14 | |
| 15 | for v in graph[u] { |
| 16 | if visited[v] == false { |
| 17 | dfs_recursive(v, mut visited, graph, mut top_sorting) |
| 18 | } |
| 19 | } |
| 20 | top_sorting << u |
| 21 | } |
| 22 | |
| 23 | // Creating aa map to initialize with of visited nodes .... all with false in the init |
| 24 | // so these nodes are NOT VISITED YET |
| 25 | fn visited_init(a_graph map[string][]string) map[string]bool { |
| 26 | mut array_of_keys := a_graph.keys() // get all keys of this map |
| 27 | mut temp := map[string]bool{} // attention in these initializations with maps |
| 28 | for i in array_of_keys { |
| 29 | temp[i] = false |
| 30 | } |
| 31 | return temp |
| 32 | } |
| 33 | |
| 34 | // attention here a map STRING ---> ONE BOOLEAN ... not a string |
| 35 | |
| 36 | fn main() { |
| 37 | // A map illustration to use in a graph |
| 38 | // the graph: adjacency matrix |
| 39 | graph_01 := { |
| 40 | 'A': ['C', 'B'] |
| 41 | 'B': ['D'] |
| 42 | 'C': ['D'] |
| 43 | 'D': [] |
| 44 | } |
| 45 | |
| 46 | graph_02 := { |
| 47 | 'A': ['B', 'C', 'D'] |
| 48 | 'B': ['E'] |
| 49 | 'C': ['F'] |
| 50 | 'D': ['G'] |
| 51 | 'E': ['H'] |
| 52 | 'F': ['H'] |
| 53 | 'G': ['H'] |
| 54 | 'H': [] // no cycles |
| 55 | } |
| 56 | // from: https://en.wikipedia.org/wiki/Topological_sorting |
| 57 | graph_03 := { |
| 58 | '5': ['11'] |
| 59 | '7': ['11', '8'] |
| 60 | '3': ['8', '10'] |
| 61 | '11': ['2', '9', '10'] |
| 62 | '8': ['9'] |
| 63 | '2': [] |
| 64 | '9': [] |
| 65 | '10': [] |
| 66 | } |
| 67 | |
| 68 | mut graph := map[string][]string{} // the graph: adjacency matrix |
| 69 | for index, g_value in [graph_01, graph_02, graph_03] { |
| 70 | println('Topological sorting for the graph ${index} using a DFS recursive') |
| 71 | graph = g_value.clone() // graphs_sample[g].clone() // choice your SAMPLE |
| 72 | |
| 73 | // mut n_nodes := graph.len |
| 74 | mut visited := visited_init(graph) // a map with nodes not visited |
| 75 | |
| 76 | // mut start := (graph.keys()).first() // arbitrary, any node if you wish |
| 77 | mut top_sorting := []string{} |
| 78 | // advantages of map ... getting all nodes |
| 79 | for i in graph.keys() { |
| 80 | if visited[i] != true { |
| 81 | dfs_recursive(i, mut visited, graph, mut top_sorting) |
| 82 | } |
| 83 | } |
| 84 | |
| 85 | print('\n A topological sorting of graph ${index} : ') |
| 86 | // println(g_value) |
| 87 | println(top_sorting.reverse()) |
| 88 | println('') |
| 89 | } // End of for |
| 90 | } |
| 91 | |