(很简单)二叉树遍历的非递归实现模板(Java代码)

先上主菜 (>.<)

就是下边的这个模板,稍微理解一下,就可以看看后边的如何使用模板(有相应习题哦)

    public List<Integer> preorderTraversal(TreeNode root) {
    	// 建立一个存储结果的集合,以及一个辅助栈
        List<Integer> list = new ArrayList<Integer>();
        Stack<TreeNode> stack = new Stack<TreeNode>();
        // 如果节点不为空,或者辅助栈不为空,一直循环
        while(root != null || !stack.isEmpty()){
        	// 先一直将左孩子入栈
            while(root != null){
            
            	// 在这里可以进行前序遍历,将 root.val存入结果集合
                ........
                
                stack.push(root);
                root = root.left;
            }
            // 弹出栈顶元素
            root = stack.pop();
            
            // 在这里可以进行中序遍历,将 root.val存入结果集合
            ........
            
            // 因为左孩子已经遍历完了,所以从栈顶弹出元素,去找右孩子
            root = root.right;
        }
        return list;
    }

前序遍历

使用一个辅助栈。前序遍历习题:传送门

    public List<Integer> preorderTraversal(TreeNode root) {
        List<Integer> list = new ArrayList<Integer>();
        Stack<TreeNode> stack = new Stack<TreeNode>();
        while(root != null || !stack.isEmpty()){
            // 循环到最左孩子
            while(root != null){
            	// ~~前序遍历,存入结果集合~~
                list.add(root.val);
                stack.push(root);
                root = root.left;
            }
            // 弹出栈顶元素
            root = stack.pop();
            // 等于它的右孩子
            root = root.right;
        }
        return list;
    }

中序遍历

使用一个辅助栈。中序遍历习题:传送门

    public List<Integer> inorderTraversal(TreeNode root) {
        List<Integer> list = new ArrayList<Integer>();
        Stack<TreeNode> stack = new Stack<TreeNode>();
        while(root!=null || !stack.isEmpty()){
            // 一直压入左孩子
           while(root != null){
                stack.push(root);
                root = root.left;
           } 
            root = stack.pop();
            // ~~中序遍历,存入结果集合~~
            list.add(root.val);
            // 等于右孩子,此后右孩子也会被压如栈中(满足条件 root!=null)
            root = root.right;
        } 
        return list;
    }

后序遍历

使用两个辅助栈,一个辅助栈用来输出反向。后序遍历习题:传送门

    public List<Integer> postorderTraversal(TreeNode root) {
        Stack<TreeNode> stackIn = new Stack<TreeNode>();
        Stack<Integer> stackOut = new Stack<Integer>();
        List<Integer> list = new ArrayList<Integer>();
        // 前序遍历:中左右     后序遍历:左右中        后序遍历反向:中右左 
        while(root != null || !stackIn.isEmpty()){
            while(root != null){
                stackIn.push(root);
                // // ~~后序遍历,存入第二个辅助栈~~ 中右左
                stackOut.push(root.val);
                // 这里较模板做了改动,先遍历所有的右孩子
                root = root.right;
            }
            root = stackIn.pop();
            // 再遍历左孩子
            root = root.left; 
        }
       // ~~后序遍历,将第二个辅助栈中的元素存入结果集合~~ 左右中
       while(!stackOut.isEmpty()){
           list.add(stackOut.pop());
       } 
        return list;
    }

后序遍历的重点是要理解:后序遍历(左右中)的反向(中左右),其实看成一个特殊的前序遍历(中左右)

我们只要将模板中的一直先入栈左孩子改动成先入栈右孩子,并且使用第二个辅助栈存储顺序。 最后将 中右左 反向输出即可

关于二叉树的层序遍历相信大家都听说过

但是,看了看网上关于前序、中序、后序遍历,递归/非递归都能实现。为什么层序遍历的递归实现没有人讲过呢?

因此,我补充了这方面的一点内容:https://blog.csdn.net/m0_47671600/article/details/106107631

你可能感兴趣的:(#,模板)