duskphantom_utils/
traverse.rs1use std::{
18 collections::{HashSet, VecDeque},
19 hash::Hash,
20};
21
22pub trait Node: Eq + Hash + Clone {
23 fn get_succ(&mut self) -> Vec<Self>;
24}
25
26pub struct POIterator<T>
28where
29 T: Node,
30{
31 container: VecDeque<T>,
32}
33
34impl<T> Iterator for POIterator<T>
35where
36 T: Node,
37{
38 type Item = T;
39 fn next(&mut self) -> Option<Self::Item> {
40 self.container.pop_front()
41 }
42}
43
44impl<T> From<T> for POIterator<T>
45where
46 T: Node,
47{
48 fn from(bb: T) -> Self {
49 let mut container = Vec::new();
51 let mut visited = HashSet::new();
52 run_postorder(bb, &mut visited, &mut container);
53
54 Self {
56 container: container.into(),
57 }
58 }
59}
60
61pub struct RPOIterator<T>
63where
64 T: Node,
65{
66 container: Vec<T>,
67}
68
69impl<T> Iterator for RPOIterator<T>
70where
71 T: Node,
72{
73 type Item = T;
74 fn next(&mut self) -> Option<Self::Item> {
75 self.container.pop()
76 }
77}
78
79impl<T> From<T> for RPOIterator<T>
80where
81 T: Node,
82{
83 fn from(bb: T) -> Self {
84 let mut container = Vec::new();
86 let mut visited = HashSet::new();
87 run_postorder(bb, &mut visited, &mut container);
88
89 Self { container }
91 }
92}
93
94fn run_postorder<T>(mut bb: T, visited: &mut HashSet<T>, container: &mut Vec<T>)
96where
97 T: Node,
98{
99 if visited.contains(&bb) {
100 return;
101 }
102 visited.insert(bb.clone());
103 for succ in bb.get_succ() {
104 run_postorder(succ.clone(), visited, container);
105 }
106 container.push(bb);
107}