use crate::graph::def::Graph;
use std::collections::VecDeque;
use cargo_snippet::snippet;
#[snippet("bfs")]
pub struct Bfs<'a, G: Graph<'a>> {
visited: Vec<bool>,
q: VecDeque<(G::NodeId, Option<G::NodeId>)>,
g: &'a G,
}
#[snippet("bfs")]
impl<'a, G: Graph<'a>> Iterator for Bfs<'a, G> {
type Item = (G::NodeId, G::NodeId);
fn next(&mut self) -> Option<Self::Item> {
if let Some((u, prev)) = self.q.pop_front() {
for v in self.g.neighbors(u) {
if !self.visited[self.g.index(v)] {
self.visited[self.g.index(v)] = true;
self.q.push_back((v, Some(u)));
}
}
if let Some(prev) = prev {
Some((prev, u))
} else {
self.next()
}
} else {
None
}
}
}
#[snippet("bfs")]
pub fn bfs<'a, G>(g: &'a G, start: G::NodeId) -> Bfs<'a, G>
where
G: Graph<'a, NodeId = usize>,
{
let n = g.len();
let mut visited = vec![false; n];
let mut q = VecDeque::new();
visited[start] = true;
q.push_back((start, None));
Bfs { visited, q, g }
}