Skip to content

Commit 8f665cf

Browse files
committed
solution 4
1 parent 7ac12f0 commit 8f665cf

File tree

1 file changed

+94
-0
lines changed

1 file changed

+94
-0
lines changed
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
package main
2+
3+
import (
4+
"sync"
5+
)
6+
7+
// ConcurrentBFSQueries concurrently processes BFS queries on the provided graph.
8+
// - graph: adjacency list, e.g., graph[u] = []int{v1, v2, ...}
9+
// - queries: a list of starting nodes for BFS.
10+
// - numWorkers: how many goroutines can process BFS queries simultaneously.
11+
//
12+
// Return a map from the query (starting node) to the BFS order as a slice of nodes.
13+
// Implementation notes:
14+
// - We spawn up to `numWorkers` goroutines that consume start-nodes from a
15+
// channel and run an independent BFS for each start node.
16+
// - Each BFS uses its own local `visited` map so there is no shared mutable
17+
// state during traversal. Results are sent back on a `results` channel and
18+
// collected by the caller goroutine which builds the final map.
19+
// - Worker goroutines are coordinated using a sync.WaitGroup; the results
20+
// channel is closed once all workers finish so the collector can range over it.
21+
func ConcurrentBFSQueries(graph map[int][]int, queries []int, numWorkers int) map[int][]int {
22+
if numWorkers <= 0 {
23+
return map[int][]int{}
24+
}
25+
26+
tasks := make(chan int)
27+
type bfsResult struct {
28+
start int
29+
order []int
30+
}
31+
results := make(chan bfsResult)
32+
33+
var wg sync.WaitGroup
34+
wg.Add(numWorkers)
35+
36+
// worker reads start nodes from tasks and performs BFS for each start
37+
worker := func() {
38+
defer wg.Done()
39+
for s := range tasks {
40+
// standard BFS using a slice as a queue
41+
visited := make(map[int]bool)
42+
order := make([]int, 0, 16)
43+
queue := make([]int, 0, 16)
44+
45+
visited[s] = true
46+
queue = append(queue, s)
47+
48+
for i := 0; i < len(queue); i++ {
49+
u := queue[i]
50+
order = append(order, u)
51+
for _, v := range graph[u] {
52+
if !visited[v] {
53+
visited[v] = true
54+
queue = append(queue, v)
55+
}
56+
}
57+
}
58+
59+
// send the result back to collector
60+
results <- bfsResult{start: s, order: order}
61+
}
62+
}
63+
64+
// start workers
65+
for i := 0; i < numWorkers; i++ {
66+
go worker()
67+
}
68+
69+
// feed tasks
70+
go func() {
71+
for _, q := range queries {
72+
tasks <- q
73+
}
74+
close(tasks)
75+
}()
76+
77+
// close results once all workers are done
78+
go func() {
79+
wg.Wait()
80+
close(results)
81+
}()
82+
83+
// collect results into the output map
84+
out := make(map[int][]int, len(queries))
85+
for r := range results {
86+
out[r.start] = r.order
87+
}
88+
89+
return out
90+
}
91+
92+
func main() {
93+
// You can insert optional local tests here if desired.
94+
}

0 commit comments

Comments
 (0)