use crate::IndexedClimber;
pub struct Postorder<C: IndexedClimber> {
climber: C,
stack: Vec<(C::Index, bool)>,
}
impl<C: IndexedClimber> Postorder<C> {
pub fn new(climber: C) -> Self {
let index = climber.index();
Self {
climber,
stack: vec![(index, false)],
}
}
}
impl<C: IndexedClimber> Iterator for Postorder<C> {
type Item = C::Item;
fn next(&mut self) -> Option<Self::Item> {
loop {
let (index, visited) = self.stack.pop()?;
let item = self.climber.go_to(&index)?;
if visited {
return Some(item);
}
self.stack.push((index, true));
self.stack.extend(
self.climber
.child_indices()
.rev()
.map(|index| (index, false)),
);
}
}
}