-
Notifications
You must be signed in to change notification settings - Fork 14
Expand file tree
/
Copy pathbfs.rs
More file actions
70 lines (58 loc) · 1.84 KB
/
Copy pathbfs.rs
File metadata and controls
70 lines (58 loc) · 1.84 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
use std::collections::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 Vec as a queue (intentionally slow)
/// Returns the order in which nodes were visited
pub fn bfs_naive(graph: &Graph, start: usize) -> Vec<usize> {
let mut visited = vec![false; graph.num_nodes()];
let mut queue = VecDeque::with_capacity(graph.num_nodes());
let mut result = Vec::with_capacity(graph.num_nodes());
queue.push_back(start);
assert!(start < graph.num_nodes());
visited[start] = true;
while let Some(node) = queue.pop_front() {
result.push(node);
if let Some(neighbors) = graph.adjacency.get(node) {
for &neighbor in neighbors {
assert!(neighbor < graph.num_nodes());
if !visited[neighbor] {
visited[neighbor] = true;
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
}