Create DFS.rs
parent
d3c2184af8
commit
f278ac80fa
|
@ -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<Vertex, HashSet<Vertex>>;
|
||||
|
||||
/**
|
||||
* 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<Vertex, u64>,
|
||||
finishing_times: HashMap<Vertex, u64>,
|
||||
parents: HashMap<Vertex, Option<Vertex>>,
|
||||
forest: VecDeque<HashSet<Vertex>>,
|
||||
topologically_sorted: VecDeque<Vertex>,
|
||||
}
|
||||
|
||||
/**
|
||||
* 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<Vertex> = HashSet::new();
|
||||
// current time
|
||||
let mut time = 0;
|
||||
|
||||
fn dfs_visit (graph: &Graph,
|
||||
vertex: Vertex,
|
||||
time: &mut u64,
|
||||
seen: &mut HashSet<Vertex>,
|
||||
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<Vertex> {
|
||||
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));
|
||||
}
|
Loading…
Reference in New Issue