#![feature(box_syntax, box_patterns)] use std::collections::VecDeque; #[derive(Debug)] struct TreeNode { value: T, left: Option>>, right: Option>>, } enum TraversalMethod { PreOrder, InOrder, PostOrder, LevelOrder, } impl TreeNode { pub fn new(arr: &[[i8; 3]]) -> TreeNode { let l = match arr[0][1] { -1 => None, i @ _ => Some(Box::new(TreeNode::::new(&arr[(i - arr[0][0]) as usize..]))), }; let r = match arr[0][2] { -1 => None, i @ _ => Some(Box::new(TreeNode::::new(&arr[(i - arr[0][0]) as usize..]))), }; TreeNode { value: arr[0][0], left: l, right: r, } } pub fn traverse(&self, tr: &TraversalMethod) -> Vec<&TreeNode> { match tr { &TraversalMethod::PreOrder => self.iterative_preorder(), &TraversalMethod::InOrder => self.iterative_inorder(), &TraversalMethod::PostOrder => self.iterative_postorder(), &TraversalMethod::LevelOrder => self.iterative_levelorder(), } } fn iterative_preorder(&self) -> Vec<&TreeNode> { let mut stack: Vec<&TreeNode> = Vec::new(); let mut res: Vec<&TreeNode> = Vec::new(); stack.push(self); while !stack.is_empty() { let node = stack.pop().unwrap(); res.push(node); match node.right { None => {} Some(box ref n) => stack.push(n), } match node.left { None => {} Some(box ref n) => stack.push(n), } } res } // Leftmost to rightmost fn iterative_inorder(&self) -> Vec<&TreeNode> { let mut stack: Vec<&TreeNode> = Vec::new(); let mut res: Vec<&TreeNode> = Vec::new(); let mut p = self; loop { // Stack parents and right children while left-descending loop { match p.right { None => {} Some(box ref n) => stack.push(n), } stack.push(p); match p.left { None => break, Some(box ref n) => p = n, } } // Visit the nodes with no right child p = stack.pop().unwrap(); while !stack.is_empty() && p.right.is_none() { res.push(p); p = stack.pop().unwrap(); } // First node that can potentially have a right child: res.push(p); if stack.is_empty() { break; } else { p = stack.pop().unwrap(); } } res } // Left-to-right postorder is same sequence as right-to-left preorder, reversed fn iterative_postorder(&self) -> Vec<&TreeNode> { let mut stack: Vec<&TreeNode> = Vec::new(); let mut res: Vec<&TreeNode> = Vec::new(); stack.push(self); while !stack.is_empty() { let node = stack.pop().unwrap(); res.push(node); match node.left { None => {} Some(box ref n) => stack.push(n), } match node.right { None => {} Some(box ref n) => stack.push(n), } } let rev_iter = res.iter().rev(); let mut rev: Vec<&TreeNode> = Vec::new(); for elem in rev_iter { rev.push(elem); } rev } fn iterative_levelorder(&self) -> Vec<&TreeNode> { let mut queue: VecDeque<&TreeNode> = VecDeque::new(); let mut res: Vec<&TreeNode> = Vec::new(); queue.push_back(self); while !queue.is_empty() { let node = queue.pop_front().unwrap(); res.push(node); match node.left { None => {} Some(box ref n) => queue.push_back(n), } match node.right { None => {} Some(box ref n) => queue.push_back(n), } } res } } fn main() { // Array representation of task tree let arr_tree = [[1, 2, 3], [2, 4, 5], [3, 6, -1], [4, 7, -1], [5, -1, -1], [6, 8, 9], [7, -1, -1], [8, -1, -1], [9, -1, -1]]; let root = TreeNode::::new(&arr_tree); for method_label in [(TraversalMethod::PreOrder, "pre-order:"), (TraversalMethod::InOrder, "in-order:"), (TraversalMethod::PostOrder, "post-order:"), (TraversalMethod::LevelOrder, "level-order:")] .iter() { print!("{}\t", method_label.1); for n in root.traverse(&method_label.0) { print!(" {}", n.value); } print!("\n"); } }