-
Notifications
You must be signed in to change notification settings - Fork 14
Expand file tree
/
Copy pathbfs.rs
More file actions
77 lines (65 loc) · 1.88 KB
/
Copy pathbfs.rs
File metadata and controls
77 lines (65 loc) · 1.88 KB
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
use std::collections::{
HashSet,
VecDeque
};
/// A simple graph represented as an adjacency list
#[derive(Debug, Clone)]
pub struct Graph {
/// adjacency[i] contains a list of nodes adjacent to node i
pub adjacency: Vec<Vec<usize>>,
}
impl Graph {
pub fn new(nodes: usize) -> Self {
Graph {
adjacency: vec![vec![]; nodes],
}
}
pub fn add_edge(&mut self, from: usize, to: usize) {
self.adjacency[from].push(to);
}
pub fn num_nodes(&self) -> usize {
self.adjacency.len()
}
}
/// Naive BFS implementation using VecDeque
/// Returns the order in which nodes were visited
pub fn bfs_naive(graph: &Graph, start: usize) -> Vec<usize> {
let n_nodes = graph.num_nodes();
let mut visited = HashSet::with_capacity(n_nodes);
let mut queue = VecDeque::with_capacity(n_nodes);
let mut result = Vec::with_capacity(n_nodes);
queue.push_back(start);
visited.insert(start);
while !queue.is_empty() {
let node = queue
.pop_front()
.expect(
"This used to be a remove(0), so I assume underlying value exists"
)
;
result.push(node);
if let Some(neighbors) = graph.adjacency.get(node) {
for &neighbor in neighbors {
if visited.insert(neighbor) {
queue.push_back(neighbor);
}
}
}
}
result
}
/// Helper function to generate a random graph for benchmarking
pub fn generate_graph(nodes: usize) -> Graph {
use rand::{Rng, SeedableRng};
let mut rng = rand::rngs::StdRng::seed_from_u64(42);
let mut graph = Graph::new(nodes);
for i in 0..nodes {
for _ in 0..10 {
let target = rng.gen_range(0..nodes);
if target != i {
graph.add_edge(i, target);
}
}
}
graph
}