diff --git a/src/tree/traversal/no_class.rs b/src/tree/traversal/no_class.rs index 9dcadbb..fef68c4 100644 --- a/src/tree/traversal/no_class.rs +++ b/src/tree/traversal/no_class.rs @@ -1,3 +1,5 @@ +//! 多种遍历方式混合的 + use datastructure::TreeNode; use std::cell::RefCell; use std::rc::Rc; @@ -18,19 +20,46 @@ pub fn build_tree(preorder: Vec, inorder: Vec) -> Option, postorder: Vec) -> Option>> { + fn build(inorder: &[i32], postorder: &[i32]) -> Option>> { + if postorder.is_empty() { + return None; + } + + let root_val = postorder.last().unwrap(); + let mut root = TreeNode::new(*root_val); + + // 题目保证值不同, 因此可以直接遍历寻找 + let root_idx = inorder.iter().position(|&x| x == *root_val).unwrap(); + let (inorder_left, inorder_right) = inorder.split_at(root_idx); + + root.left = build(inorder_left, &postorder[..inorder_left.len()]); + root.right = build( + &inorder_right[1..], + &postorder[inorder_left.len()..postorder.len() - 1], + ); + Some(Rc::new(RefCell::new(root))) + } + + build(&inorder, &postorder) +} + #[cfg(test)] mod tests { use macros::tree; @@ -47,4 +76,15 @@ mod tests { tree!({3, left: {9}, right:{20, left: {15}, right:{7} }}) ); } + + #[test] + fn test_build_tree2() { + let inorder = vec![9, 3, 15, 20, 7]; + let postorder = vec![9, 15, 7, 20, 3]; + let root = build_tree2(inorder, postorder); + assert_eq!( + root, + tree!({3, left: {9}, right:{20, left: {15}, right:{7} }}) + ); + } }