graph.go 915 B

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. package grok
  2. type graph map[string][]string
  3. func reverseList(s []string) (r []string) {
  4. for _, i := range s {
  5. i := i
  6. defer func() { r = append(r, i) }()
  7. }
  8. return
  9. }
  10. func sortGraph(g graph) (order, cyclic []string) {
  11. L := make([]string, len(g))
  12. i := len(L)
  13. temp := map[string]bool{}
  14. perm := map[string]bool{}
  15. var cycleFound bool
  16. var cycleStart string
  17. var visit func(string)
  18. visit = func(n string) {
  19. switch {
  20. case temp[n]:
  21. cycleFound = true
  22. cycleStart = n
  23. return
  24. case perm[n]:
  25. return
  26. }
  27. temp[n] = true
  28. for _, m := range g[n] {
  29. visit(m)
  30. if cycleFound {
  31. if cycleStart > "" {
  32. cyclic = append(cyclic, n)
  33. if n == cycleStart {
  34. cycleStart = ""
  35. }
  36. }
  37. return
  38. }
  39. }
  40. delete(temp, n)
  41. perm[n] = true
  42. i--
  43. L[i] = n
  44. }
  45. for n := range g {
  46. if perm[n] {
  47. continue
  48. }
  49. visit(n)
  50. if cycleFound {
  51. return nil, cyclic
  52. }
  53. }
  54. return L, nil
  55. }