Skip to content

Commit 7fd0db7

Browse files
committed
add a depth_first_search helper function
1 parent 4c91bb9 commit 7fd0db7

File tree

3 files changed

+49
-1
lines changed

3 files changed

+49
-1
lines changed

src/librustc_data_structures/graph/iterate/mod.rs

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use super::super::indexed_vec::IndexVec;
2-
use super::{DirectedGraph, WithSuccessors, WithNumNodes};
2+
use super::{DirectedGraph, WithNumNodes, WithSuccessors};
3+
use crate::bit_set::BitSet;
34

45
#[cfg(test)]
56
mod test;
@@ -51,3 +52,36 @@ pub fn reverse_post_order<G: DirectedGraph + WithSuccessors + WithNumNodes>(
5152
vec.reverse();
5253
vec
5354
}
55+
56+
/// A "depth-first search" iterator for a directed graph.
57+
pub struct DepthFirstSearch<'graph, G>
58+
where
59+
G: ?Sized + DirectedGraph + WithNumNodes + WithSuccessors,
60+
{
61+
graph: &'graph G,
62+
stack: Vec<G::Node>,
63+
visited: BitSet<G::Node>,
64+
}
65+
66+
impl<G> DepthFirstSearch<'graph, G>
67+
where
68+
G: ?Sized + DirectedGraph + WithNumNodes + WithSuccessors,
69+
{
70+
pub fn new(graph: &'graph G, start_node: G::Node) -> Self {
71+
Self { graph, stack: vec![start_node], visited: BitSet::new_empty(graph.num_nodes()) }
72+
}
73+
}
74+
75+
impl<G> Iterator for DepthFirstSearch<'_, G>
76+
where
77+
G: ?Sized + DirectedGraph + WithNumNodes + WithSuccessors,
78+
{
79+
type Item = G::Node;
80+
81+
fn next(&mut self) -> Option<G::Node> {
82+
let DepthFirstSearch { stack, visited, graph } = self;
83+
let n = stack.pop()?;
84+
stack.extend(graph.successors(n).filter(|&m| visited.insert(m)));
85+
Some(n)
86+
}
87+
}

src/librustc_data_structures/graph/mod.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,13 @@ where
3030
&'graph self,
3131
node: Self::Node,
3232
) -> <Self as GraphSuccessors<'graph>>::Iter;
33+
34+
fn depth_first_search(&self, from: Self::Node) -> iterate::DepthFirstSearch<'_, Self>
35+
where
36+
Self: WithNumNodes,
37+
{
38+
iterate::DepthFirstSearch::new(self, from)
39+
}
3340
}
3441

3542
pub trait GraphSuccessors<'graph> {

src/librustc_data_structures/graph/vec_graph/test.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,3 +44,10 @@ fn succesors() {
4444
assert_eq!(graph.successors(5), &[1]);
4545
assert_eq!(graph.successors(6), &[]);
4646
}
47+
48+
#[test]
49+
fn dfs() {
50+
let graph = create_graph();
51+
let dfs: Vec<_> = graph.depth_first_search(0).collect();
52+
assert_eq!(dfs, vec![0, 1, 3, 4, 2]);
53+
}

0 commit comments

Comments
 (0)