拓扑排序可以判断一个有向图是否存在环,若存在环则不存在拓扑排序,一个图的拓扑排序可能不止一种
流程
- 如果一个节点不存在依赖节点,则入栈,并标记为
DONE,后续遍历到DONE节点可以直接过 - 如果一个节点存在依赖节点,则
- 将该节点标记为
DOING - 遍历依赖节点,如果依赖节点也为
DOING,则发现环,不存在拓扑排序 - 若不存在环,入栈,并标记为
DONE
- 直到遍历完所有节点
代码实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| const DOING int = 1 const DONE int = 2
func findTopologicalOrder(num int, edges [][]int) []int { ans := make([]int, 0, num)
flag := make([]int, num) m := make(map[int][]int) for _, req := range edges { m[req[0]] = append(m[req[0]], req[1]) }
var dfs func(i int) bool dfs = func(i int) bool { if flag[i] == DONE { return true } else if flag[i] == DOING { return false } flag[i] = DOING deps := m[i] for _, dep := range deps { if !dfs(dep) { return false } }
ans = append(ans, i) flag[i] = DONE
return true }
for i := 0; i < num; i++ { if !dfs(i) { return []int{} } }
return ans }
|