diff --git a/algorithms/Rust/DFS.rs b/algorithms/Rust/DFS.rs new file mode 100644 index 00000000..caea0609 --- /dev/null +++ b/algorithms/Rust/DFS.rs @@ -0,0 +1,103 @@ +use std::collections::HashMap; +use std::collections::HashSet; +use std::collections::vec_deque::VecDeque; +use std::ops::AddAssign; + +type Vertex = u64; +type Graph = HashMap>; + +/** + * Constructs a graph from a sequence of parent child pairs + */ +pub fn from_pairs(pairs: &[(u64, u64)]) -> Graph { + let mut graph: Graph = HashMap::new(); + for &(parent, child) in pairs { + let children = graph.entry(parent).or_insert(HashSet::new()); + children.insert(child); + } + return graph; +} + +#[derive(Debug)] +pub struct DFSResult { + starting_times: HashMap, + finishing_times: HashMap, + parents: HashMap>, + forest: VecDeque>, + topologically_sorted: VecDeque, +} + +/** + * Returns the starting and finishing times and the parents of every node + * found with dfs as well as the dfs forest + */ +pub fn dfs(graph: &Graph) -> DFSResult { + let mut state = DFSResult { + // The DFS forest + forest: VecDeque::new(), + // all the starting times for each vertex + starting_times: HashMap::new(), + // the finishing times for each vertex + finishing_times: HashMap::new(), + // the parents of each vertex + parents: HashMap::new(), + // the topologically sorted list of verticies + topologically_sorted: VecDeque::new(), + }; + + // the verticies that bave been seen so far + let mut seen: HashSet = HashSet::new(); + // current time + let mut time = 0; + + fn dfs_visit (graph: &Graph, + vertex: Vertex, + time: &mut u64, + seen: &mut HashSet, + state: &mut DFSResult) { + + time.add_assign(1); + state.starting_times.insert(vertex, *time); + seen.insert(vertex); + + let mut branch = state.forest.pop_back().expect("The Forest should not be empty!"); + branch.insert(vertex); + state.forest.push_back(branch); + + for neighbor in graph.get(&vertex).unwrap_or(&HashSet::new()) { + if !seen.contains(neighbor) { + state.parents.insert(*neighbor, Option::Some(vertex)); + dfs_visit(graph, *neighbor, time, seen, state); + } + } + + time.add_assign(1); + state.finishing_times.insert(vertex, *time); + state.topologically_sorted.push_front(vertex); + }; + + for vertex in graph.keys() { + state.parents.insert(*vertex, Option::None); + } + + for vertex in graph.keys() { + if !seen.contains(vertex) { + state.forest.push_back(HashSet::new()); + dfs_visit(graph, *vertex, &mut time, &mut seen, &mut state); + } + } + return state; +} + +fn topological_sort(graph: &Graph) -> VecDeque { + let DFSResult{topologically_sorted, ..} = dfs(graph); + return topologically_sorted +} + +fn main() { + let pairs = [(1, 2), (2, 1)]; + let g = from_pairs(&pairs); + println!("{:?}", g); + println!("{:?}", dfs(&g)); + println!("{:?}", topological_sort(&g)); +}