Skip to content

Commit

Permalink
feat(dfs): make DFS more efficient by using IndexSet internally
Browse files Browse the repository at this point in the history
This requires an API change as using an `IndexSet` requires the type to
implement `Hash`.
  • Loading branch information
samueltardieu committed Mar 24, 2024
1 parent 1ef8a9a commit 884e7d5
Showing 1 changed file with 9 additions and 6 deletions.
15 changes: 9 additions & 6 deletions src/directed/dfs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ use std::collections::HashSet;
use std::hash::Hash;
use std::iter::FusedIterator;

use crate::FxIndexSet;

/// Compute a path using the [depth-first search
/// algorithm](https://en.wikipedia.org/wiki/Depth-first_search).
/// The path starts from `start` up to a node for which `success` returns `true` is computed and
Expand Down Expand Up @@ -45,18 +47,19 @@ use std::iter::FusedIterator;
/// ```
pub fn dfs<N, FN, IN, FS>(start: N, mut successors: FN, mut success: FS) -> Option<Vec<N>>
where
N: Eq,
N: Eq + Hash,
FN: FnMut(&N) -> IN,
IN: IntoIterator<Item = N>,
FS: FnMut(&N) -> bool,
{
let mut path = vec![start];
step(&mut path, &mut successors, &mut success).then_some(path)
let mut path = FxIndexSet::default();
path.insert(start);
step(&mut path, &mut successors, &mut success).then_some(Vec::from_iter(path))
}

fn step<N, FN, IN, FS>(path: &mut Vec<N>, successors: &mut FN, success: &mut FS) -> bool
fn step<N, FN, IN, FS>(path: &mut FxIndexSet<N>, successors: &mut FN, success: &mut FS) -> bool
where
N: Eq,
N: Eq + Hash,
FN: FnMut(&N) -> IN,
IN: IntoIterator<Item = N>,
FS: FnMut(&N) -> bool,
Expand All @@ -67,7 +70,7 @@ where
let successors_it = successors(path.last().unwrap());
for n in successors_it {
if !path.contains(&n) {
path.push(n);
path.insert(n);
if step(path, successors, success) {
return true;
}
Expand Down

0 comments on commit 884e7d5

Please sign in to comment.