-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathgraph.go
83 lines (69 loc) · 1.46 KB
/
graph.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
package main
type Node struct {
Val int
}
type Graph struct {
Nodes []*Node
Edges map[Node]map[Node]struct{}
}
func (g *Graph) AddNode(n *Node) {
g.Nodes = append(g.Nodes, n)
}
func (g *Graph) AddEdge(n1, n2 *Node) {
if _, ok := g.Edges[*n1]; !ok {
g.Edges[*n1] = make(map[Node]struct{})
}
g.Edges[*n1][*n2] = struct{}{}
if _, ok := g.Edges[*n2]; !ok {
g.Edges[*n2] = make(map[Node]struct{})
}
g.Edges[*n2][*n1] = struct{}{}
}
func NewGraph() *Graph {
return &Graph{
Nodes: make([]*Node, 0),
Edges: make(map[Node]map[Node]struct{}),
}
}
// entry point for Depth First Search
func (g *Graph) DFS(start Node) <-chan Node {
visited := make(map[Node]struct{})
res := make(chan Node)
go func() {
g.dfs(visited, start, res)
close(res)
}()
return res
}
// private recursive Depth First Search
func (g *Graph) dfs(visited map[Node]struct{}, n Node, res chan<- Node) {
visited[n] = struct{}{}
res <- n
for k := range g.Edges[n] {
if _, ok := visited[k]; !ok {
g.dfs(visited, k, res)
}
}
}
// entry point for Breadth First Search
func (g *Graph) BFS(start Node) <-chan Node {
ch := make(chan Node)
go func() {
toVisit := []Node{start}
visited := map[Node]struct{}{start: {}}
ch <- start
for len(toVisit) > 0 {
elem := toVisit[0]
toVisit = toVisit[1:]
for k := range g.Edges[elem] {
if _, ok := visited[k]; !ok {
visited[k] = struct{}{}
ch <- k
toVisit = append(toVisit, k)
}
}
}
close(ch)
}()
return ch
}