栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

java前中后 遍历 递归与非递归

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

java前中后 遍历 递归与非递归

public class TreeTraversal {
    public void preOrder(TreeNode root){
        // 先序递归
        if (root == null){
            return;
        }
        // 根左右 每个节点都访问三次
        System.out.println("root.val = " + root.val);
        preOrder(root.left);
        preOrder(root.right);
    }

    
    public void preOrderWithoutRecursive(TreeNode root){
        // 问题1 : 忘记校验root
        if (root == null){
            return;
        }
        // 思路 递归本质是栈,借助栈来实现非递归的先序遍历
        linkedList stack = new linkedList<>();
        // 根节点入栈,栈不空就继续遍历
        stack.add(root);
        while (!stack.isEmpty()){
            // 由于先序,直接出栈并打印
            TreeNode popNode = stack.pop();
            // 先序遍历
            System.out.println("popNode.val = " + popNode.val);
            // 子节点入栈,继续遍历,不断的根 左 右
            // 栈结构逆反所以 右 左 入栈
            // 问题2:忘记校验左右非空 牢记参数校验
            if (popNode.right!= null){
                stack.push(popNode.right);
            }

            // 左侧节点永远比右侧先出栈被遍历到
            if (popNode.left!= null){
                stack.push(popNode.left);
            }
        }

    }


    
    public void inOrder(TreeNode root){
        // 递归
        if (root == null){
            return;
        }
        // 左根右 每个节点都访问三次
        inOrder(root.left);
        // 中序就是在第二次访问到自身时输出/做事
        System.out.println("root.val = " + root.val);
        inOrder(root.right);
    }

    
    public void inOrderWithoutRecursive(TreeNode root){
        // 问题1 : 忘记校验root
        if (root == null){
            return;
        }
        // 思路 递归本质是栈,借助栈来实现非递归的中序遍历
        linkedList stack = new linkedList<>();
        // 根节点入栈,栈不空就继续遍历
        stack.add(root);
        while (!stack.isEmpty()){
            // 如果遍历左侧非空则一直入栈
            if(root.left != null){
                stack.push(root.left);
                root = root.left;
            }else{
                // 遍历到左侧底部,由于一层循环
                // 直接出栈并访问
                TreeNode popNode = stack.pop();
                System.out.println(popNode.val);
                // 判断是否需要访问右侧
                if(popNode.right != null){
                    root = popNode.right;
                    stack.push(popNode.right);
                }
            }


        }

    }

    
    public void inOrderWithoutRecursive1(TreeNode root){
        // 问题1 : 忘记校验root
        if (root == null){
            return;
        }
        // 思路 递归本质是栈,借助栈来实现非递归的中序遍历
        linkedList stack = new linkedList<>();
        // 优化 直接遍历 更加符合语义
        while (root != null || !stack.isEmpty()){
            // 如果遍历左侧非空则一直入栈
            if(root != null){
                // 直接放入而不是左侧了
                stack.push(root);
                root = root.left;
            }else{
                // 遍历到左侧底部,由于一层循环
                // 直接出栈并访问
                TreeNode popNode = stack.pop();
                System.out.println(popNode.val);
                // 优化 直接访问右侧
                root = popNode.right;
            }


        }

    }

    
    public void postOrder(TreeNode root){
        // 递归
        if (root == null){
            return;
        }
        // 左右根 每个节点都访问三次
        postOrder(root.left);
        postOrder(root.right);
        // 后序就是在第三次访问到自身时输出/做事
        System.out.println("root.val = " + root.val);
    }

    
    public void postOrderWithoutRecursive(TreeNode root){
        // 问题1 : 忘记校验root
        if (root == null){
            return;
        }
        // 思路 递归本质是栈,借助栈来实现非递归的后序
        // 后序与先序做比较 先序 根 左 右 后序 左 右 根
        // 后序的逆转 根 右 左
        // 先序非递归是右左入栈所以出栈是左右,后序只要左右入栈出栈就是右左,后序就是先序的逆反+栈输出,出栈入辅助后逆序输出
        linkedList stack1 = new linkedList<>();
        linkedList stack2 = new linkedList<>();
        // 根节点入栈
        stack1.push(root);
        while (!stack1.isEmpty()){
            // 先序是先输出,后序直接入栈 并且由于出栈特性,每个节点都只访问一次 不会出现重复入栈的动作
            TreeNode popNode = stack1.pop();
            stack2.push(popNode);
            // 左右遍历即可
            if (popNode.left != null){
                stack1.push(popNode.left);
            }
            if (popNode.right != null){
                stack1.push(popNode.right);
            }
        }
        while (!stack2.isEmpty()){
            // 错误 应该直接访问stack2
//            System.out.println("stack1.pop().val = " + stack1.pop().val);
            System.out.println("stack2.pop().val = " + stack2.pop().val);
        }


    }

}

   class TreeNode {
      int val;
      TreeNode left;
      TreeNode right;
      TreeNode() {}
      TreeNode(int val) { this.val = val; }
      TreeNode(int val, TreeNode left, TreeNode right) {
          this.val = val;
          this.left = left;
          this.right = right;
      }
  }
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/322514.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号