前言
練習5.11: 現在線性代數的老師把微積分設爲了前置課程。完善topSort,使其能檢測有向圖中的環。
沒找到5.11的參考Go語言版,參考C語言版本的思路,結合原有的代碼邏輯,在最小改動的原則上實現了Go語言版本的深度優先遍歷拓撲排序環檢測。
5.10、5.12 可參考 https://blog.csdn.net/taoshihan/article/details/101249100
參考的C語言版本 https://blog.csdn.net/qq_40507857/article/details/84305444
實現邏輯
用三種狀態來標記訪問的節點:未訪問、正在訪問、已訪問;
初始情況,均爲未訪問;
未訪問項訪問時設置爲正在訪問,遞歸訪問該項的前序課程,訪問結束後設置爲已訪問;
若正在訪問時遇到一個正在訪問的課程,說明存在環,標記,退出。
代碼
package main
import (
"fmt"
"sort"
)
func topoSort(m map[string][]string) map[int]string {
var order = make(map[int]string)
index := 0
seen := make(map[string]int) // 初始值默認爲0, 與下面notvisit狀態相對應
const (
notvisit = iota
visiting //正在訪問
visited // 訪問結束
)
hasRing := false
var visitAll func(items []string)
visitAll = func(items []string) {
if hasRing {
return
}
for _, item := range items {
if seen[item] == notvisit{
seen[item] = visiting
//fmt.Printf("visiting: %v\n", item)
visitAll(m[item])
order[index] = item
index++
seen[item] = visited
}else if seen[item] == visiting {
//fmt.Printf("already visit: %v\n", item)
hasRing = true
return
}
}
}
var keys []string
for key := range m {
keys = append(keys, key)
}
visitAll(keys)
if hasRing {
fmt.Printf("found ring\n");
order = make(map[int]string)
}
return order
}
func main() {
results = topoSort(prereqs)
for i:=0; i<len(results); i++ {
fmt.Printf("%d:\t%s\n", i+1, results[i])
}
}
var prereqs = map[string][]string{
"algorithms": {"data structures"},
"calculus": {"linear algebra"},
"linear algebra": {"calculus"},
"compilers": {
"data structures",
"formal languages",
"computer organization",
},
"data structures": {"discrete math"},
"databases": {"data structures"},
"discrete math": {"intro to programming"},
"formal languages": {"discrete math"},
"networks": {"operating systems"},
"operating systems": {"data structures", "computer organization"},
"programming languages": {"data structures", "computer organization"},
}
輸出
case 1 prereqs 加入 “linear algebra”: {“calculus”},
found ring
case 2 prereqs 不加入 “linear algebra”: {“calculus”},
1: intro to programming
2: discrete math
3: data structures
4: algorithms
5: calculus
6: linear algebra
7: formal languages
8: computer organization
9: operating systems
10: networks
11: programming languages
12: compilers
13: databases