• By Golang

    By Golang

    1. // Package graph creates a ItemGraph data structure for the Item type
    2. package graph
    3. import (
    4. "fmt"
    5. "sync"
    6. )
    7. // Item the type of the binary search tree
    8. type Item interface{}
    9. // Node a single node that composes the tree
    10. type Node struct {
    11. value Item
    12. }
    13. func (n *Node) String() string {
    14. return fmt.Sprintf("%v", n.value)
    15. }
    16. // ItemGraph the Items graph
    17. type ItemGraph struct {
    18. nodes []*Node
    19. edges map[Node][]*Node
    20. lock sync.RWMutex
    21. }
    22. // AddNode adds a node to the graph
    23. func (g *ItemGraph) AddNode(n *Node) {
    24. g.lock.Lock()
    25. g.nodes = append(g.nodes, n)
    26. g.lock.Unlock()
    27. }
    28. // AddEdge adds an edge to the graph
    29. func (g *ItemGraph) AddEdge(n1, n2 *Node) {
    30. g.lock.Lock()
    31. if g.edges == nil {
    32. g.edges = make(map[Node][]*Node)
    33. }
    34. g.edges[*n1] = append(g.edges[*n1], n2)
    35. g.edges[*n2] = append(g.edges[*n2], n1)
    36. g.lock.Unlock()
    37. }
    38. // AddEdge adds an edge to the graph
    39. func (g *ItemGraph) String() {
    40. g.lock.RLock()
    41. s := ""
    42. for i := 0; i < len(g.nodes); i++ {
    43. s += g.nodes[i].String() + " -> "
    44. near := g.edges[*g.nodes[i]]
    45. for j := 0; j < len(near); j++ {
    46. s += near[j].String() + " "
    47. }
    48. s += "\n"
    49. }
    50. fmt.Println(s)
    51. g.lock.RUnlock()
    52. }
    53. // Traverse implements the BFS traversing algorithm
    54. func (g *ItemGraph) Traverse(f func(*Node)) {
    55. g.lock.RLock()
    56. q := NodeQueue{}
    57. q.New()
    58. n := g.nodes[0]
    59. q.Enqueue(*n)
    60. visited := make(map[*Node]bool)
    61. for {
    62. if q.IsEmpty() {
    63. break
    64. }
    65. node := q.Dequeue()
    66. visited[node] = true
    67. near := g.edges[*node]
    68. for i := 0; i < len(near); i++ {
    69. j := near[i]
    70. if !visited[j] {
    71. q.Enqueue(*j)
    72. visited[j] = true
    73. }
    74. }
    75. if f != nil {
    76. f(node)
    77. }
    78. }
    79. g.lock.RUnlock()
    80. }