Skip to content

Commit ce2fc6b

Browse files
committed
add bread first paths
1 parent 153f289 commit ce2fc6b

File tree

2 files changed

+126
-0
lines changed

2 files changed

+126
-0
lines changed

bread_first_paths.go

+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
package algo
2+
3+
// BreadFirstPaths ...
4+
type BreadFirstPaths struct {
5+
marked []bool
6+
edgeTo []int
7+
s int
8+
}
9+
10+
// NewBreadFirstPaths ...
11+
func NewBreadFirstPaths(g *Graph, s int) *BreadFirstPaths {
12+
b := &BreadFirstPaths{marked: make([]bool, g.V()), edgeTo: make([]int, g.V()), s: s}
13+
b.Bfs(g, s)
14+
return b
15+
}
16+
17+
// Bfs ...
18+
func (s *BreadFirstPaths) Bfs(g *Graph, v int) {
19+
s.marked[v] = true
20+
queue := NewQueue()
21+
queue.Enqueue(v)
22+
for !queue.IsEmpty() {
23+
v := queue.Dequeue().(int)
24+
for _, w := range g.Adj(v) {
25+
if !s.marked[w] {
26+
s.edgeTo[w] = v
27+
s.marked[w] = true
28+
queue.Enqueue(w)
29+
}
30+
}
31+
}
32+
}
33+
34+
// HasPathTo ...
35+
func (s *BreadFirstPaths) HasPathTo(v int) bool {
36+
return s.marked[v]
37+
}
38+
39+
// PathTo ...
40+
func (s *BreadFirstPaths) PathTo(v int) []int {
41+
if !s.HasPathTo(v) {
42+
return nil
43+
}
44+
path := NewStack()
45+
for x := v; x != s.s; x = s.edgeTo[x] {
46+
path.Push(x)
47+
}
48+
path.Push(s.s)
49+
vertexes := []int{}
50+
for _, x := range path.Slice() {
51+
vertexes = append(vertexes, x.(int))
52+
}
53+
return vertexes
54+
}

cmd/bread-first-paths/main.go

+72
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
/******************************************************************************
2+
* Execution: go run cmd/bread-first-paths/main.go G s
3+
* Dependencies: Graph.java Queue.java Stack.java StdOut.java
4+
* Data files: https://algs4.cs.princeton.edu/41graph/tinyCG.txt
5+
* https://algs4.cs.princeton.edu/41graph/tinyG.txt
6+
* https://algs4.cs.princeton.edu/41graph/mediumG.txt
7+
* https://algs4.cs.princeton.edu/41graph/largeG.txt
8+
*
9+
* Run breadth first search on an undirected graph.
10+
* Runs in O(E + V) time.
11+
*
12+
* % go run cmd/graph/main.go tinyCG.txt
13+
* 6 8
14+
* 0: 2 1 5
15+
* 1: 0 2
16+
* 2: 0 1 3 4
17+
* 3: 5 4 2
18+
* 4: 3 2
19+
* 5: 3 0
20+
*
21+
* % go run cmd/bread-first-paths/main.go tinyCG.txt 0
22+
* 0 to 0 (0): 0
23+
* 0 to 1 (1): 0-1
24+
* 0 to 2 (1): 0-2
25+
* 0 to 3 (2): 0-2-3
26+
* 0 to 4 (2): 0-2-4
27+
* 0 to 5 (1): 0-5
28+
*
29+
* % go run cmd/bread-first-paths/main.go largeG.txt 0
30+
* 0 to 0 (0): 0
31+
* 0 to 1 (418): 0-932942-474885-82707-879889-971961-...
32+
* 0 to 2 (323): 0-460790-53370-594358-780059-287921-...
33+
* 0 to 3 (168): 0-713461-75230-953125-568284-350405-...
34+
* 0 to 4 (144): 0-460790-53370-310931-440226-380102-...
35+
* 0 to 5 (566): 0-932942-474885-82707-879889-971961-...
36+
* 0 to 6 (349): 0-932942-474885-82707-879889-971961-...
37+
*
38+
******************************************************************************/
39+
40+
package main
41+
42+
import (
43+
"fmt"
44+
"os"
45+
"strconv"
46+
47+
"github.com/shellfly/algo"
48+
"github.com/shellfly/algo/stdin"
49+
)
50+
51+
func main() {
52+
graph := algo.NewGraph(stdin.NewIn(os.Args[1]))
53+
s, _ := strconv.Atoi(os.Args[2])
54+
p := algo.NewBreadFirstPaths(graph, s)
55+
56+
for v := 0; v < graph.V(); v++ {
57+
if p.HasPathTo(v) {
58+
fmt.Printf("%d to %d: ", s, v)
59+
for _, x := range p.PathTo(v) {
60+
if x == s {
61+
fmt.Print(x)
62+
} else {
63+
fmt.Printf("-%d", x)
64+
}
65+
}
66+
fmt.Println()
67+
} else {
68+
fmt.Printf("%d and %d: not connected\n", s, v)
69+
}
70+
}
71+
72+
}

0 commit comments

Comments
 (0)