二叉树的遍历

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();
        }
    }
相关推荐
huaweichenai2 小时前
spring boot对接阿里短信
java·spring boot
KING-WU5122 小时前
Linux 工具之Make 与 Makefile
java·linux·服务器
Tisfy3 小时前
LeetCode 0301.删除无效的括号:二进制枚举 / 回溯
算法·leetcode·字符串·题解·回溯·括号匹配·二进制枚举
马剑威(威哥爱编程)3 小时前
【AI全栈后端12-08】Spring Boot 用 MCP 统一接入内部系统:让 AI 接一次,全公司复用
java·人工智能·spring boot
Nil2083 小时前
leetcode 322零钱兑换
算法·leetcode·职场和发展
顽疲3 小时前
从零用 Java 实现小红书 SpringBoot Vue UniApp(23)笔记话题多对多:一条笔记进多个话题池
java·vue.js·spring boot
海绵宝宝转agent3 小时前
2026-10-9 leetcode100刷题+面经整理
笔记·算法·面试
yi0113 小时前
DAY24: LeetCode 167:两数之和 II|从暴力枚举到左右双指针
笔记·python·算法·leetcode·二分查找·双指针
木井巳3 小时前
【BFS 解决拓扑排序】课程表
java·算法·leetcode·广度优先·宽度优先·推荐算法·图搜索算法
Crazy________3 小时前
05Linux内存管理核心原理与运维实战
java·开发语言