1+ ---
2+ difficulty : Medium
3+ tags :
4+ - Geeks for Geeks
5+ - Topological Sort
6+ - LintCode Copyright
7+ - BFS
8+ - DFS
9+ title : Topological Sorting
10+ ---
11+
112# Topological Sorting
213
3- ## Question
14+ ## Problem
415
5- - lintcode: [ (127) Topological Sorting] ( http://www.lintcode.com/en/problem/topological-sorting/ )
6- - [ Topological Sorting - GeeksforGeeks] ( http://www.geeksforgeeks.org/topological-sorting/ )
16+ ### Metadata
17+
18+ - tags: Geeks for Geeks, Topological Sort, LintCode Copyright, BFS, DFS
19+ - difficulty: Medium
20+ - source(lintcode): < https://www.lintcode.com/problem/topological-sorting/ >
21+ - source(geeksforgeeks): < http://www.geeksforgeeks.org/topological-sorting/ >
22+
23+ ### Description
724
8- ```
925Given an directed graph, a topological order of the graph nodes is defined as follow:
1026
11- For each directed edge A -> B in graph, A must before B in the order list.
12- The first node in the order can be any node in the graph with no nodes direct to it.
27+ - For each directed edge ` A -> B ` in graph, A must before B in the order list.
28+ - The first node in the order can be any node in the graph with no nodes direct to it.
29+
1330Find any topological order for the given graph.
14- ```
15- Example
16- For graph as follow:
1731
18- ![ Topological Sorting] ( ../../shared-files/images/topological_sorting.jpeg )
32+ #### Notice
33+
34+ You can assume that there is at least one topological order in the graph.
35+
36+ #### Clarification
37+
38+ [ Learn more about representation of graphs] ( http://www.lintcode.com/help/graph " Graph example ")
39+
40+ #### Example
41+
42+ For graph as follow:
43+
44+ ![ picture] ( ../../shared-files/images/topological-sorting.jpeg )
45+
1946
20- ```
2147The topological order can be:
2248
23- [0, 1, 2, 3, 4, 5]
24- [0, 2, 3, 1, 5, 4]
25- ...
26- Note
27- You can assume that there is at least one topological order in the graph.
49+ [0, 1, 2, 3, 4, 5]
50+ [0, 2, 3, 1, 5, 4]
51+ ...
52+
53+ #### Challenge
2854
29- Challenge
3055Can you do it in both BFS and DFS?
31- ```
3256
33- ## 题解1 - DFS and BFS
57+ ## 题解1 - DFS
3458
35- 图搜索相关的问题较为常见的解法是用 DFS,这里结合 BFS 进行求解,分为三步走 :
59+ 图搜索相关的问题较为常见的解法是用 DFS 或者 BFS,这里我们先分析一下拓扑排序的核心要求:对于有向边 ` A -> B ` , A 需要出现在 B 之前。用过 Linux/MAC 的人对包管理工具肯定不陌生,如 apt-get, yum, pacman, brew 等,安装一项软件时往往要先将其所有依赖的软件包安装完。这个需求实现起来大概可以分为如下几个步骤 :
3660
37- 1 . 统计各定点的入度——只需统计节点在邻接列表中出现的次数即可知。
38- 2 . 遍历图中各节点,找到入度为0的节点。
39- 3 . 对入度为0的节点进行递归 DFS,将节点加入到最终返回结果中。
61+ 1 . 找出不依赖其他顶点的顶点,即入度为0,这一定是符合要求的某一个拓扑排序的第一个顶点。
62+ 2 . 在图中去掉入度为 0 的顶点,并重新计算一次各顶点的入度,递归调用邻居节点,迭代第一步。
63+
64+ 在具体实现中,考虑到每次取出某个顶点时重新计算其余顶点的入度存在较多重复计算,我们可以将计算量缩减到只计算入度有变化的部分顶点,即所取出顶点的邻居节点。
4065
4166### C++
4267
@@ -105,9 +130,65 @@ private:
105130};
106131```
107132
133+ ### Java
134+
135+ ```java
136+ /**
137+ * Definition for Directed graph.
138+ * class DirectedGraphNode {
139+ * int label;
140+ * ArrayList<DirectedGraphNode> neighbors;
141+ * DirectedGraphNode(int x) { label = x; neighbors = new ArrayList<DirectedGraphNode>(); }
142+ * };
143+ */
144+
145+ public class Solution {
146+ /*
147+ * @param graph: A list of Directed graph node
148+ * @return: Any topological order for the given graph.
149+ */
150+ public ArrayList<DirectedGraphNode> topSort(ArrayList<DirectedGraphNode> graph) {
151+ ArrayList<DirectedGraphNode> sorting = new ArrayList<>();
152+ Map<DirectedGraphNode, Integer> inDegreeMap = getIndegreeMap(graph);
153+ for (Map.Entry<DirectedGraphNode, Integer> degreeMap : inDegreeMap.entrySet()) {
154+ if (degreeMap.getValue() == 0) {
155+ dfs(inDegreeMap, degreeMap.getKey(), sorting);
156+ }
157+ }
158+
159+ return sorting;
160+ }
161+
162+ private Map<DirectedGraphNode, Integer> getIndegreeMap(ArrayList<DirectedGraphNode> graph) {
163+ Map<DirectedGraphNode, Integer> inDegreeMap = new HashMap<>();
164+ for (DirectedGraphNode node : graph) {
165+ inDegreeMap.putIfAbsent(node, 0);
166+ for (DirectedGraphNode neighbor : node.neighbors) {
167+ inDegreeMap.putIfAbsent(neighbor, 0);
168+ inDegreeMap.put(neighbor, inDegreeMap.get(neighbor) + 1);
169+ }
170+ }
171+
172+ return inDegreeMap;
173+ }
174+
175+ private void dfs(Map<DirectedGraphNode, Integer> inDegreeMap, DirectedGraphNode node, List<DirectedGraphNode> result) {
176+
177+ result.add(node);
178+ inDegreeMap.put(node, inDegreeMap.get(node) - 1);
179+ for (DirectedGraphNode neighbor : node.neighbors) {
180+ inDegreeMap.put(neighbor, inDegreeMap.get(neighbor) - 1);
181+ if (inDegreeMap.get(neighbor) == 0) {
182+ dfs(inDegreeMap, neighbor, result);
183+ }
184+ }
185+ }
186+ }
187+ ```
188+
108189### 源码分析
109190
110- C++中使用 unordered_map 可获得更高的性能,私有方法中使用引用传值。
191+ C++中使用 unordered_map 可获得更高的性能,私有方法中使用引用传值。在 ` dfs ` 递归的过程中,将节点加入到最终结果后需要对其入度减一,否则在上层循环邻居节点时会有重复。这里的 ` dfs ` 是伪 DFS, 因为这里只处理入度为 0 的节点。
111192
112193### 复杂度分析
113194
@@ -121,7 +202,7 @@ C++中使用 unordered_map 可获得更高的性能,私有方法中使用引
121202
122203## 题解2 - BFS
123204
124- 拓扑排序除了可用 DFS 求解外,也可使用 BFS, 具体方法为:
205+ 拓扑排序除了可用 DFS 求解外,也可使用 BFS, 相比题解1使用递归获取入度为 0 的节点,我们还可以通过队列获取非邻居节点的其他入度为 0 的节点。 具体方法为:
125206
1262071 . 获得图中各节点的入度。
1272082 . BFS 首先遍历求得入度数为0的节点,入队,便于下一次 BFS。
@@ -212,3 +293,4 @@ C++中在判断入度是否为0时将对 map 产生副作用,在求入度数
212293## Reference
213294
214295- [Topological Sorting 参考程序 Java/C++/Python](http://www.jiuzhang.com/solutions/topological-sorting/)
296+ - [Topological Sorting - GeeksforGeeks](https://www.geeksforgeeks.org/topological-sorting/)
0 commit comments