Skip to content

Instantly share code, notes, and snippets.

@timClicks
Created February 15, 2022 03:19
Show Gist options
  • Save timClicks/0aab3721adf482f1f59d64a09a2bc9a3 to your computer and use it in GitHub Desktop.
Save timClicks/0aab3721adf482f1f59d64a09a2bc9a3 to your computer and use it in GitHub Desktop.
Breadth-first search in Rust
// watch the video if you would like an explanation of this code
// https://youtu.be/FoNJ5zhL6bQ
use std::collections::{HashSet, VecDeque};
use std::hash::Hash;
trait Graph {
type Node: Hash + Eq + Clone + std::fmt::Debug;
fn neighbours(&self, node: &Self::Node) -> Vec<Self::Node>;
}
fn bfs<G: Graph>(g: G, start: G::Node) {
let mut queue = VecDeque::new();
let mut visited = HashSet::new();
queue.push_front(start);
while let Some(node) = queue.pop_front() {
println!("{:?}", node);
// if we have found goal, return here
for neighbour in g.neighbours(&node) {
if visited.contains(&neighbour) {
continue;
}
// use queue.push_front(neighbour) for depth-first search
queue.push_back(neighbour);
}
visited.insert(node);
}
}
// Example implementation - fully connected grid
struct Grid {
bounds: (i32, i32),
}
impl Graph for Grid {
type Node = (i32, i32);
fn neighbours(&self, node: &(i32, i32)) -> Vec<(i32, i32)> {
let (x, y) = *node;
let mut others = vec![];
if x > 0 {
others.push((x - 1, y));
}
if x < self.bounds.0 {
others.push((x + 1, y));
}
if y > 0 {
others.push((x, y - 1));
}
if y < self.bounds.1 {
others.push((x, y + 1));
}
others
}
}
fn main() {
let grid = Grid { bounds: (10, 10) };
bfs(grid, (5, 8));
}
@oylenshpeegul
Copy link

Isn't it still pushing things onto the queue more than once? I think we need to add

        if visited.contains(&node) {
            continue;
        }

before line 20.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment