二叉树的遍历

1.递归版

java 复制代码
    public static class TreeNode{
        public int val;
        public TreeNode left;
        public TreeNode right;

        public TreeNode(int val){
            this.val = val;
        }
    }
    // 先序: (根) -> 左 -> 右
    // 中序: 左 -> (根) -> 右
    // 后序: 左 -> 右 -> (根)
    public static void f(TreeNode head){
        if (head == null) {
            return;
        }
        // 1
        f(head.left);
        // 2
        f(head.right);
        // 3
    }
    // 先序遍历,递归
    public static void preOrder(TreeNode head){
        if (head == null) {
            return;
        }
        System.out.println(head.val + " ");
        preOrder(head.left);
        preOrder(head.right);
    }
    // 中序遍历,递归
    public static void inOrder(TreeNode head){
        if (head == null) {
            return;
        }
        inOrder(head.left);
        System.out.println(head.val + " ");
        inOrder(head.right);
    }
    // 后序遍历,递归
    public static void posOrder(TreeNode head){
        if (head == null) {
            return;
        }
        posOrder(head.left);
        posOrder(head.right);
        System.out.println(head.val + " ");
    }

2.非递归版

2.1 先序遍历

java 复制代码
    // 先序打印 非递归
    public static void preOrder(TreeNode head){
        if (head != null) {
            Stack<TreeNode> stack = new Stack<>();
            stack.push(head);
            while (!stack.isEmpty()) {
                head = stack.pop();
                System.out.println(head.val + " ");
                if (head.right != null) {
                    stack.push(head.right);
                }
                if (head.left != null) {
                    stack.push(head.left);
                }
            }
            System.out.println();
        }
    }

2.2中序遍历

java 复制代码
    // 中序打印 非递归
    // 1.子树头、左边界进栈
    // 2.栈弹出一个节点打印,节点右树进栈
    // 3.没有子树且栈空
    public static void inOrder(TreeNode head){
        if (head != null) {
            Stack<TreeNode> stack = new Stack<>();
            while (!stack.isEmpty() || head == null) {
                if (head != null) {
                    stack.push(head);
                    head = head.left;
                }
                else {
                    head = stack.pop();
                    System.out.println(head.val + " ");
                    head = head.right;
                }
            }
            System.out.println();
        }
    }

2.3后续遍历(1)

java 复制代码
    // 后续打印
    // 先序: (根) -> 左 -> 右
    // 先序': (根) -> 右 -> 左
    // 反转: 左 -> 右 -> (根)
    public static void posOrder(TreeNode head){
        if (head != null) {
            Stack<TreeNode> stack = new Stack<>();
            Stack<TreeNode> collect = new Stack<>();
            stack.push(head);
            while (!stack.isEmpty()) {
                head = stack.pop();
                collect.push(head);
                if (head.left != null) {
                    stack.push(head.left);
                }
                if (head.right != null) {
                    stack.push(head.right);
                }     
            }
            while (!collect.isEmpty()) {
                System.out.println(collect.pop().val + " ");
            }
        }
    }

2.4后续遍历(2)

java 复制代码
    public static void posOrderOneStack(TreeNode h){
        if (h != null) {
            Stack<TreeNode> stack = new Stack<>();
            stack.push(h);
            // 如果始终没有打印节点,h就一直是头结点
            // 一旦打印过节点,h就变成打印节点
            // 之后h含义:上一次打印的节点
            while (!stack.isEmpty()) {
                TreeNode cur = stack.peek();
                if (cur.left != null
                    && h != cur.left
                    && h != cur.right) {
                        // 有左树且左树未处理
                    stack.push(cur.left);
                }
                else if (cur.right != null
                        && h != cur.right) {
                        // 有右树且右树未处理
                    stack.push(cur.right);
                }
                else{
                    // 没有左树 右树 或者左树右树都处理了
                    System.out.println(cur.val + " ");
                    h = stack.pop();
                }
            }
            System.out.println();
        }
    }
相关推荐
郭小李14 小时前
springmvc 拦截器
java·开发语言·前端
大风起兮云飞扬丶14 小时前
Java——日期类
java·开发语言
Wang's Blog14 小时前
Java 项目实战:交友项目 - 联系人管理需求分析
java·开发语言·交友
lazy H14 小时前
【计算机网络】第 13 篇:NAT 和端口映射是什么?为什么本地服务外网访问不了?
java·网络·网络协议·学习·计算机网络·408
学到老活到老14 小时前
第 22 集:Filter、Interceptor、AOP 都能拦截,为什么不能互换?
java·后端·spring
sun032215 小时前
【JDK 动态代理】 和 【CGLIB 代理】对比
java·数据库·sql
文丑颜不良啊15 小时前
LeetCode1261~1280题目解析
java·leetcode
郭小李15 小时前
spring 中的 @EnableWebMvc注解和WebMvcConfigurer接口
java·后端·spring
not coder15 小时前
一文讲通--从树到红黑树
数据结构·算法
octopus_c15 小时前
C++ 入门
开发语言·c++·算法