有向图遍历
深度优先遍历
func depthFirst(m map[string][]string) []string {
var order []string
seen := make(map[string]bool)
var visitAll func(items []string)
visitAll = func(items []string) {
for _, item := range items {
if !seen[item] {
seen[item] = true
visitAll(m[item])
order = append(order, item)
}
}
}
var keys []string
for key := range m {
keys = append(keys, key)
}
sort.Strings(keys)
visitAll(keys)
return order
}
广度优先遍历(目前遍历方向不对)
func breadthFirst(m map[string][]string) []string {
var order []string
seen := make(map[string]bool)
var visitAll func(worklist []string)
visitAll = func(worklist []string) {
for len(worklist) > 0 {
items := worklist
worklist = nil
for _, item := range items {
if !seen[item] {
seen[item] = true
order = append(order, item)
worklist = append(worklist, m[item]...)
}
}
}
}
var keys []string
for key := range m {
keys = append(keys, key)
}
visitAll(keys)
return order
}
测试数据
func main() {
results := breadthFirst(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"},
"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"},
}
判断回路
判断回路主要有两种方法:一种是深度优先遍历的方法,一种是拓扑排序的方法
深度优先遍历
func topoSort(m map[string][]string) []string {
var order []string
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
visitAll(m[item])
order = append(order, item)
seen[item] = visited
}else if seen[item] == visiting {
hasRing = true
return
}
}
}
var keys []string
for key := range m {
keys = append(keys, key)
}
visitAll(keys)
if hasRing {
fmt.Printf("found ring\n");
order := []string
}
return order
}
拓扑排序
func IsContain(items []string, item string) bool {
for _, eachItem := range items {
if eachItem == item {
return true
}
}
return false
}
func topoSort(m map[string][]string) []string {
var order []string
seen := make(map[string]bool)
hasRing := false
count := 0 // record the visted node
var count_last int // compare to find the ring
// collect all the items
keysMap := make(map[string]bool)
for k, v := range m {
keysMap[k] = true
for _, x := range v {
keysMap[x] = true
}
}
var keys []string
for key := range keysMap {
keys = append(keys, key)
}
if len(keys) == 0 {
return order
}
// calculus the node's indegree
indegree := make(map[string]int)
for _,k := range keys {
list, ok := m[k];
if ok {
indegree[k] = len(list)
} else {
indegree[k] = 0
}
}
for {
if count < len(keys) {
count_last = count
for _, item := range keys {
if !seen[item] && indegree[item] == 0 {
order = append(order, item)
seen[item] = true
count++
// update the indegree
for k, v := range m {
if IsContain(v, item){
indegree[k]--
}
}
}
}
} else {
break
}
if count_last == count && count != len(keys)-1 {
hasRing = true
break
}
}
if hasRing {
fmt.Printf("found ring\n")
order = []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"},
}
参考文献:<<go语言圣经>>

本文探讨了如何使用Go语言进行有向图的深度优先和广度优先遍历,并介绍了利用这两种方法来判断图中是否存在回路。深度优先遍历和拓扑排序是判断回路的主要技术,通过实际的测试数据进行了验证。
1499

被折叠的 条评论
为什么被折叠?



