Go語言聖經練習5.11

前言

練習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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章