itertree/
lib.rs

1#![warn(dead_code)]
2#![warn(unused_imports)]
3
4#[derive(Debug)]
5pub struct Node<'a, T> {
6    left: Option<Box<Node<'a, T>>>,
7    right: Option<Box<Node<'a, T>>>,
8    pub contents: &'a T,
9}
10
11impl<'a, T> Node<'a, T> {
12    pub fn new(arr: &[(i32, i32, i32, T)]) -> Node<T> {
13        let (idx, left, right, contents) = &arr[0];
14        let l = match left {
15            -1 => None,
16            i => Some(Box::new(Node::new(&arr[(i - idx) as usize..]))),
17        };
18        let r = match right {
19            -1 => None,
20            i => Some(Box::new(Node::new(&arr[(i - idx) as usize..]))),
21        };
22        Node {
23            contents: contents,
24            left: l,
25            right: r,
26        }
27    }
28
29    pub fn iter(&self, order: TraversalOrder) -> NodeIterPre<T> {
30        NodeIterPre::new(self, order)
31    }
32}
33
34impl<'a, T> PartialEq for Node<'a, T> {
35    fn eq(&self, other: &Node<T>) -> bool {
36        self as *const _ == other as *const _
37    }
38}
39
40#[derive(Debug)]
41pub enum TraversalOrder {
42    /// Uses: create a copy of the tree. Also prefix expressions like RPN.
43    PreOrder,
44    /// Uses: for binary search trees, gives ascending order.
45    InOrder,
46    /// Uses: can be used to delete the tree, or parts of it.
47    PostOrder,
48}
49
50pub struct NodeIterPre<'a, T> {
51    stack: Vec<&'a Node<'a, T>>,
52    order: TraversalOrder,
53    node: Option<&'a Node<'a, T>>,
54    last_visited_node: Option<&'a Node<'a, T>>,
55}
56
57impl<'a, T> NodeIterPre<'a, T> {
58    fn new(node: &'a Node<'a, T>, order: TraversalOrder) -> NodeIterPre<'a, T> {
59        match order {
60            TraversalOrder::PreOrder =>
61                NodeIterPre {
62                    stack: vec![node],
63                    order,
64                    node: None,
65                    last_visited_node: None,
66                },
67            TraversalOrder::InOrder =>
68                NodeIterPre {
69                    stack: vec![],
70                    order,
71                    node: Some(node),
72                    last_visited_node: None,
73                },
74            TraversalOrder::PostOrder =>
75                NodeIterPre {
76                    stack: vec![],
77                    order,
78                    node: Some(node),
79                    last_visited_node: None,
80                }
81        }
82    }
83
84    fn next_preorder(&mut self) -> Option<&'a Node<'a, T>> {
85        let stack = &mut self.stack;
86        match stack.pop() {
87            None => None,
88            Some(n) => {
89                if let Some(bn) = &n.right {
90                    stack.push(bn.as_ref());
91                };
92                if let Some(bn) = &n.left {
93                    stack.push(bn.as_ref());
94                };
95                Some(n)
96            }
97        }
98    }
99
100    fn next_inorder(&mut self) -> Option<&'a Node<'a, T>> {
101        let stack = &mut self.stack;
102        let r = loop {
103            if self.node.is_some() {
104                let n = self.node.unwrap();
105                stack.push(n);
106                self.node = match &n.left {
107                    None => None,
108                    Some(left) => Some(left.as_ref()),
109                };
110            } else {
111                let result = stack.pop();
112                match result {
113                    None => {},
114                    Some(r) => {
115                        self.node = match &r.right {
116                            None => None,
117                            Some(rr) => Some(rr.as_ref()),
118                        }
119                    }
120                }
121                break result;
122            }
123        };
124        r
125    }
126
127    fn next_postorder(&mut self) -> Option<&'a Node<'a, T>> {
128        let r= loop {
129            if self.node.is_some() {
130                let n = self.node.unwrap();
131                self.stack.push(n);
132                self.node = match &n.left {
133                    None => None,
134                    Some(left) => Some(left.as_ref()),
135                };
136            } else {
137                let peek_node = self.stack.last();
138                // if right child exists and traversing node from
139                // left child, then move right.
140                if let Some(pk) = peek_node {
141                    let right = match &pk.right {
142                        None => None,
143                        Some(r) => Some(r.as_ref()),
144                    };
145                    if right.is_some() && self.last_visited_node.is_some() && *self.last_visited_node.unwrap() != *right.unwrap() {
146                        self.node = right;
147                    } else {
148                        self.last_visited_node = self.stack.pop();
149                        // break Some(peek_node);
150                        break self.last_visited_node;
151                    }
152                } else {
153                    break None;
154                }
155            }
156        };
157        r
158    }
159
160}
161
162impl<'a, T> Iterator for NodeIterPre<'a, T> {
163    type Item = &'a Node<'a, T>;
164
165    fn next(&mut self) -> Option<&'a Node<'a, T>> {
166        let r = match self.order {
167            TraversalOrder::PreOrder => self.next_preorder(),
168            TraversalOrder::InOrder => self.next_inorder(),
169            TraversalOrder::PostOrder => self.next_postorder(),
170        };
171        r
172    }
173}
174
175#[allow(dead_code)]
176fn make_tree() {
177    let arr_tree = [
178        (1, 2, 3, 1),
179        (2, 4, 5, 2),
180        (3, 6, -1, 3),
181        (4, 7, -1, 4),
182        (5, -1, -1, 5),
183        (6, 8, 9, 6),
184        (7, -1, -1, 7),
185        (8, -1, -1, 8),
186        (9, -1, -1, 9)
187    ];
188
189    let tree = Node::new(&arr_tree);
190    println!("{:?}", &tree);
191
192    let orders = vec![
193        TraversalOrder::PreOrder,
194        TraversalOrder::InOrder,
195        TraversalOrder::PostOrder,
196    ];
197    for order in orders {
198        println!();
199        println!("{:?}", &order);
200        tree.iter(order).for_each(
201            |n| print!("{:?} ", &n.contents)
202        );
203    }
204}
205
206#[cfg(test)]
207mod tests {
208    use super::*;
209
210    #[test]
211    fn test_base() {
212        println!("{}", 123);
213        make_tree();
214        assert_eq!(1, 1);
215    }
216
217}