94. 二叉树的中序遍历-非递归方式

每天一道Rust-LeetCode(2019-08-11)

坚持每天一道题,刷题学习Rust.

题目描述

给定一个二叉树,返回它的中序 遍历。

示例:

输入: [1,null,2,3]
   1
    \
     2
    /
   3

输出: [1,3,2]

进阶: 递归算法很简单,你可以通过迭代算法完成吗?

解题过程

use crate::share::TreeNode;
use std::cell::RefCell;
use std::rc::Rc;
impl Solution {
 
    pub fn inorder_traversal2(root: Option<Rc<RefCell<TreeNode>>>) -> Vec<i32> {
        let mut v = Vec::new();
        Solution::inorder_non_recursive(root, &mut v);
        v
    }
    /*
        将指定节点从自身到最深的最左边path压栈
    //! ```text
    //!      3
    //!     /  \
    //!    /    \
    //!   1      5 <-[Node index, a.k.a, Position]
    //!  / \    / \
    //! 0   2  4   6
    //!
    //! 0   1  2   3 <[Leaf index]
    //! ```
        比如,传递进来3,
        那么就会压栈[3,1,0]
        */
    fn pushNodes(mut root: Option<Rc<RefCell<TreeNode>>>, stack: &mut Vec<Rc<RefCell<TreeNode>>>) {
        while let Some(r) = root {
            stack.push(r.clone());
            root = r.borrow().left.clone();
        }
        return;
    }
    /*
    思路, 首先将最左边整条路径压栈
    然后取出来一个,打印,然后尝试访问
    */
     fn inorder_non_recursive(root: Option<Rc<RefCell<TreeNode>>>, v: &mut Vec<i32>) {
        let mut nodes = Vec::new();
        Solution::pushNodes(root, &mut nodes);
        //while let 显然更rust
        while let Some(n) = nodes.pop() {
            v.push(n.borrow().val);
            /*
            压栈右子树,如果有的话
            */
            Solution::pushNodes(n.borrow().right.clone(), &mut nodes);
        }
        return;
    }
}
#[cfg(test)]
mod test {
    use super::*;
    use crate::share::build_tree;
    use crate::share::NULL;
    #[test]
    fn test_inorder_traversal() {
        let t = build_tree(&vec![1, NULL, 2, NULL, NULL, 3]);
        println!("t={:?}", t);
        let t2 = t.unwrap();
        assert_eq!(
            Solution::inorder_traversal2(Some(t2.clone())),
            vec![1, 3, 2]
        );
    }
}

一点感悟

换成非递归,说白了就是用自定义Stack数据结构来模拟递归
在libra中明确不要使用unwrap,如果要用也要用expect,这是一个好习惯.

其他

欢迎关注我的github,本项目文章所有代码都可以找到.