By Golang
// Package graph creates a ItemGraph data structure for the Item typepackage graphimport ( "fmt" "sync")// Item the type of the binary search treetype Item interface{}// Node a single node that composes the treetype Node struct { value Item}func (n *Node) String() string { return fmt.Sprintf("%v", n.value)}// ItemGraph the Items graphtype ItemGraph struct { nodes []*Node edges map[Node][]*Node lock sync.RWMutex}// AddNode adds a node to the graphfunc (g *ItemGraph) AddNode(n *Node) { g.lock.Lock() g.nodes = append(g.nodes, n) g.lock.Unlock()}// AddEdge adds an edge to the graphfunc (g *ItemGraph) AddEdge(n1, n2 *Node) { g.lock.Lock() if g.edges == nil { g.edges = make(map[Node][]*Node) } g.edges[*n1] = append(g.edges[*n1], n2) g.edges[*n2] = append(g.edges[*n2], n1) g.lock.Unlock()}// AddEdge adds an edge to the graphfunc (g *ItemGraph) String() { g.lock.RLock() s := "" for i := 0; i < len(g.nodes); i++ { s += g.nodes[i].String() + " -> " near := g.edges[*g.nodes[i]] for j := 0; j < len(near); j++ { s += near[j].String() + " " } s += "\n" } fmt.Println(s) g.lock.RUnlock()}// Traverse implements the BFS traversing algorithmfunc (g *ItemGraph) Traverse(f func(*Node)) { g.lock.RLock() q := NodeQueue{} q.New() n := g.nodes[0] q.Enqueue(*n) visited := make(map[*Node]bool) for { if q.IsEmpty() { break } node := q.Dequeue() visited[node] = true near := g.edges[*node] for i := 0; i < len(near); i++ { j := near[i] if !visited[j] { q.Enqueue(*j) visited[j] = true } } if f != nil { f(node) } } g.lock.RUnlock()}