二叉树的遍历

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();
        }
    }
相关推荐
一只齐刘海的猫13 小时前
【Leetcode】乘积最大子数组
算法·leetcode·职场和发展
程序员黑豆13 小时前
什么是JDK以及JDK都由哪些部分组成呢
java·前端·ai编程
估值探索者13 小时前
【Python实时盯盘与预警 #08】成交额突然放大2倍?Python窗口比较抓异动
java·开发语言·python
凤山老林13 小时前
Spring Boot 定时任务进阶:动态 Cron 与集群防重实战
java·spring boot·后端·定时任务·集群定时任务
余生皆假期-14 小时前
傅里叶变换和拉普拉斯变换
人工智能·算法·机器学习
xbgRS14 小时前
spring整合mybaits
java·spring·mybatis
不一样的故事12614 小时前
芯片设计是一个高度复杂、分工精细的系统工程
数据结构·经验分享
数模竞赛Paid answer15 小时前
2026年五一杯数学建模C题边坡预警问题求解全过程文档及程序
算法·数学建模·五一杯
梁辰兴15 小时前
软件工程:面向数据结构的设计方法
数据结构·软件工程·梁辰兴·面向数据结构的设计方法·jackson方法·warnier方法·方法比较
hold?fish:palm15 小时前
20 旋转图像
c++·算法·leetcode