use std::{
collections::{HashSet, VecDeque},
hash::Hash,
};
pub trait Node: Eq + Hash + Clone {
fn get_succ(&mut self) -> Vec<Self>;
}
pub struct POIterator<T>
where
T: Node,
{
container: VecDeque<T>,
}
impl<T> Iterator for POIterator<T>
where
T: Node,
{
type Item = T;
fn next(&mut self) -> Option<Self::Item> {
self.container.pop_front()
}
}
impl<T> From<T> for POIterator<T>
where
T: Node,
{
fn from(bb: T) -> Self {
let mut container = Vec::new();
let mut visited = HashSet::new();
run_postorder(bb, &mut visited, &mut container);
Self {
container: container.into(),
}
}
}
pub struct RPOIterator<T>
where
T: Node,
{
container: Vec<T>,
}
impl<T> Iterator for RPOIterator<T>
where
T: Node,
{
type Item = T;
fn next(&mut self) -> Option<Self::Item> {
self.container.pop()
}
}
impl<T> From<T> for RPOIterator<T>
where
T: Node,
{
fn from(bb: T) -> Self {
let mut container = Vec::new();
let mut visited = HashSet::new();
run_postorder(bb, &mut visited, &mut container);
Self { container }
}
}
fn run_postorder<T>(mut bb: T, visited: &mut HashSet<T>, container: &mut Vec<T>)
where
T: Node,
{
if visited.contains(&bb) {
return;
}
visited.insert(bb.clone());
for succ in bb.get_succ() {
run_postorder(succ.clone(), visited, container);
}
container.push(bb);
}