二叉树的非递归遍历

2020-08-17  本文已影响0人  bangbang2

非递归遍历的一般手法

利用栈,先不断的找到最左边的节点,然后依次压入栈中,然后栈中元素pop,再向右去找子树,前序遍历和中序遍历比较简单
前序遍历:中左右的顺序,会先在压栈时就将加入list中
中序遍历是在pop后进行加入list

 public List<Integer> preorderTraversal(TreeNode root) {
         Stack<TreeNode> stack=new Stack<TreeNode>();
         List<Integer> list=new ArrayList<Integer>();
        while(!stack.empty()||root!=null){
            while(root!=null){
              list.add(root.val);
              stack.push(root);
              root=root.left;
            }
            root=stack.pop();
            root=root.right;
        }
       return list;
    }

主要的难点的后序遍历:
首先需要判断当前节点是不是叶子节点(有没有左孩子或右孩子)或其右子树已经被访问过
有疑问看代码注释

public List<Integer> postorderTraversal(TreeNode root) {
        List<Integer> res = new LinkedList<>();
        Stack<TreeNode> stack = new Stack<>();

        TreeNode cur = root;
        TreeNode last = null;
        while(cur != null || !stack.isEmpty()) {
            while(cur != null) {
                stack.push(cur);
                cur = cur.left;
            }
            cur = stack.peek();//不能pop,需要判断当前节点是不是叶子节点
            if (cur.right == null || cur.right == last) { // 右孩子为空或者访问过了,默认左子树为空,不然就跳不///出那个while循环
                res.add(cur.val); 
                stack.pop();
                last = cur;//标记为刚被访问的节点
                cur = null; //为什么要标记为null,咋说了,一旦满足是叶子节点或右子树已经被访问后,说明这棵子树////已经结束了,需要再从栈里取元素
            } else {
                cur = cur.right;//如果有右子树没有被访问,需要去将右子树压入栈中
            }
        }

        return res;
    }
上一篇 下一篇

猜你喜欢

热点阅读