radiate_gp/collections/trees/
iter.rs1use crate::collections::{Tree, TreeNode};
2use std::collections::VecDeque;
3
4pub trait TreeIterator<T> {
53 fn iter_pre_order(&self) -> PreOrderIterator<T>;
54 fn iter_post_order(&self) -> PostOrderIterator<T>;
55 fn iter_breadth_first(&self) -> TreeBreadthFirstIterator<T>;
56}
57
58impl<T> TreeIterator<T> for TreeNode<T> {
62 fn iter_pre_order(&self) -> PreOrderIterator<T> {
63 PreOrderIterator { stack: vec![self] }
64 }
65
66 fn iter_post_order(&self) -> PostOrderIterator<T> {
67 PostOrderIterator {
68 stack: vec![(self, false)],
69 }
70 }
71
72 fn iter_breadth_first(&self) -> TreeBreadthFirstIterator<T> {
73 TreeBreadthFirstIterator {
74 queue: vec![self].into_iter().collect(),
75 }
76 }
77}
78
79impl<T> TreeIterator<T> for Tree<T> {
83 fn iter_pre_order(&self) -> PreOrderIterator<T> {
84 PreOrderIterator {
85 stack: self
86 .root()
87 .map_or(Vec::new(), |root| vec![root].into_iter().collect()),
88 }
89 }
90
91 fn iter_post_order(&self) -> PostOrderIterator<T> {
92 PostOrderIterator {
93 stack: self
94 .root()
95 .map_or(Vec::new(), |root| vec![(root, false)].into_iter().collect()),
96 }
97 }
98 fn iter_breadth_first(&self) -> TreeBreadthFirstIterator<T> {
99 TreeBreadthFirstIterator {
100 queue: self
101 .root()
102 .map_or(VecDeque::new(), |root| vec![root].into_iter().collect()),
103 }
104 }
105}
106
107pub struct PreOrderIterator<'a, T> {
108 stack: Vec<&'a TreeNode<T>>,
109}
110
111impl<'a, T> Iterator for PreOrderIterator<'a, T> {
112 type Item = &'a TreeNode<T>;
113
114 fn next(&mut self) -> Option<Self::Item> {
115 self.stack.pop().map(|node| {
116 if let Some(children) = node.children() {
118 for child in children.iter().rev() {
119 self.stack.push(child);
120 }
121 }
122 node
123 })
124 }
125}
126
127pub struct PostOrderIterator<'a, T> {
128 stack: Vec<(&'a TreeNode<T>, bool)>,
129}
130
131impl<'a, T> Iterator for PostOrderIterator<'a, T> {
132 type Item = &'a TreeNode<T>;
133
134 fn next(&mut self) -> Option<Self::Item> {
135 while let Some((node, visited)) = self.stack.pop() {
136 if visited {
137 return Some(node);
138 }
139 self.stack.push((node, true));
140 if let Some(children) = node.children() {
141 for child in children.iter().rev() {
142 self.stack.push((child, false));
143 }
144 }
145 }
146 None
147 }
148}
149
150pub struct TreeBreadthFirstIterator<'a, T> {
151 queue: VecDeque<&'a TreeNode<T>>,
152}
153
154impl<'a, T> Iterator for TreeBreadthFirstIterator<'a, T> {
155 type Item = &'a TreeNode<T>;
156
157 fn next(&mut self) -> Option<Self::Item> {
158 let node = self.queue.pop_front()?;
159 if let Some(children) = node.children() {
160 self.queue.extend(children.iter());
161 }
162 Some(node)
163 }
164}
165
166#[cfg(test)]
167mod tests {
168 use super::*;
169 use crate::collections::{Tree, TreeNode};
170
171 use crate::Op;
172 use crate::node::Node;
173 use crate::ops::operation;
174
175 #[test]
176 fn test_tree_traversal() {
177 let leaf = Op::constant(4.0);
184 let node2 = TreeNode::with_children(Op::constant(2.0), vec![TreeNode::new(leaf)]);
185
186 let node3 = TreeNode::new(Op::constant(3.0));
187
188 let root = Tree::new(TreeNode::with_children(
189 Op::constant(1.0),
190 vec![node2, node3],
191 ));
192
193 let pre_order: Vec<f32> = root
195 .iter_pre_order()
196 .map(|n| match &n.value() {
197 operation::Op::Const(_, v) => *v,
198 _ => panic!("Expected constant but got {:?}", n.value()),
199 })
200 .collect();
201 assert_eq!(pre_order, vec![1.0, 2.0, 4.0, 3.0]);
202
203 let post_order: Vec<f32> = root
205 .iter_post_order()
206 .map(|n| match &n.value() {
207 operation::Op::Const(_, v) => *v,
208 _ => panic!("Expected constant"),
209 })
210 .collect();
211 assert_eq!(post_order, vec![4.0, 2.0, 3.0, 1.0]);
212
213 let bfs: Vec<f32> = root
215 .iter_breadth_first()
216 .map(|n| match &n.value() {
217 operation::Op::Const(_, v) => *v,
218 _ => panic!("Expected constant"),
219 })
220 .collect();
221 assert_eq!(bfs, vec![1.0, 2.0, 3.0, 4.0]);
222 }
223}