二叉树的遍历 Java

二叉树的遍历

java 复制代码
public 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;
    }
}

递归法

前序、中序、后序怎么区分?

前、中、后其实描述的是,根节点(一颗树有左子树、根节点、右子树)的访问时间。

前序遍历:根节点->左子树->右子树。

中序遍历:左子树->根节点->右子树。

后序遍历:左子树->右子树->根节点。

LeetCode题目:144.二叉树的前序遍历、94.二叉树的中序遍历、145.二叉树的后序遍历。

前序遍历

java 复制代码
class Solution {
    List<Integer> mylist = new ArrayList<Integer>();

    public List<Integer> preorderTraversal(TreeNode root) {
        if(root == null) return mylist;
        mylist.add(root.val);
        preorderTraversal(root.left);
        preorderTraversal(root.right);
        return mylist;
    }
}

中序遍历

java 复制代码
class Solution {
    List<Integer> mylist = new ArrayList<Integer>();
    public List<Integer> inorderTraversal(TreeNode root) {
        if(root == null) return mylist;
        inorderTraversal(root.left);
        mylist.add(root.val);
        inorderTraversal(root.right);
        return mylist;
    }
}

后序遍历

java 复制代码
class Solution {
    List<Integer> mylist = new ArrayList<Integer>();
    public List<Integer> postorderTraversal(TreeNode root) {
        if(root == null) return mylist;
        postorderTraversal(root.left);
        postorderTraversal(root.right);
        mylist.add(root.val);
        return mylist;
    }
}

改进

以前序遍历为例,以下是代码随想录的代码。

java 复制代码
class Solution {
    public List<Integer> preorderTraversal(TreeNode root) {
        List<Integer> result = new ArrayList<Integer>();
        preorder(root, result);
        return result;
    }

    public void preorder(TreeNode root, List<Integer> result) {
        if (root == null) {
            return;
        }
        result.add(root.val);
        preorder(root.left, result);
        preorder(root.right, result);
    }
}

迭代法

以下是笔记,from 代码随想录

编程语言实现递归的逻辑,是用栈这种数据结构实现的。

前序、后序遍历

注意,栈操作中,判断是否为空的方法,有两个,isEmpty 和 empty 都可以。

前序:

前序遍历是 根左右,所以压入栈的顺序应该是右、左

java 复制代码
class Solution {
    public List<Integer> preorderTraversal(TreeNode root) {
        Stack<TreeNode> s = new Stack<>();
        List<Integer> ans = new  ArrayList<Integer>();

        if(root == null) return ans;
        else s.push(root);

        while(!s.isEmpty()) {
            TreeNode tmp = s.pop();
            ans.add(tmp.val);
            if(tmp.right != null) s.push(tmp.right);
            if(tmp.left != null) s.push(tmp.left);
        }

        return ans;
    }
}


后序:

前序遍历顺序是 根左右,后续是左右根,只需要把上文中的前序遍历的顺序变成 根右左,然后反转结果数组/list就可以。

反转的方法: Collections.reverse(ans);

java 复制代码
class Solution {
    public List<Integer> postorderTraversal(TreeNode root) {
        List<Integer> ans = new ArrayList<>();
        if(root == null) return ans;

        Stack<TreeNode> stack = new Stack<>();
        stack.push(root);
        while(!stack.isEmpty()) {
            TreeNode tmp = stack.pop();
            ans.add(tmp.val);
            if(tmp.left != null) stack.push(tmp.left);
            if(tmp.right != null) stack.push(tmp.right);
        }
        Collections.reverse(ans);
        return ans;
    }
}

中序遍历

中序遍历的访问顺序和处理顺序是不一样的。一棵树,是从根节点开始访问的。前序遍历的根左右顺序保证了访问顺序和处理顺序相同。

但是中序遍历的顺序是左根右。

分析:

中序遍历的顺序是左根右,处理完所有的左子树、再处理根节点、最后处理所有的右子树。

因为代码中是用根节点root定位一棵树的,遍历树的时候从根节点开始,但是中序遍历处理(处理的意思在这里就是把节点的值加入到数组中)不是先处理根节点。

所以用栈先存下所有的左子树,处理完根节点之后再处理左子树。

java 复制代码
class Solution {  
    public List<Integer> inorderTraversal(TreeNode root) {
        List<Integer> ans = new ArrayList<>();
        if(root == null) return ans;

        Stack<TreeNode> mystack = new Stack<>();
        TreeNode cur = root;
        while(cur != null || !mystack.isEmpty()) {
            if(cur != null) {
                mystack.push(cur);
                cur = cur.left;
            } else {
                cur = mystack.pop();
                ans.add(cur.val);
                cur = cur.right;
            }
        }
        return ans;
    }
}

二叉树的统一迭代法(未完成)

Java 中 null、NULL、nullptr 区别

(1)NULL 不是 Java 中的关键字

(2)nullptr 不是 Java 中的关键字

(3)在 Java 中,null 表示"没有值"或"空"。它是一个关键字,用于表示一个对象变量不引用任何对象。这意味着该变量没有指向任何有效的内存地址

相关推荐
A阳俊yi17 分钟前
Spring Boot日志配置
java·spring boot·后端
苹果酱056717 分钟前
2020-06-23 暑期学习日更计划(机器学习入门之路(资源汇总)+概率论)
java·vue.js·spring boot·mysql·课程设计
echo17542542 分钟前
Apipost免费版、企业版和私有化部署详解
java
异常君1 小时前
Java 高并发编程:等值判断的隐患与如何精确控制线程状态
java·后端·代码规范
异常君1 小时前
Java 日期处理:SimpleDateFormat 线程安全问题及解决方案
java·后端·代码规范
都叫我大帅哥1 小时前
Spring AI中的ChatClient:从入门到精通,一篇搞定!
java·spring·ai编程
都叫我大帅哥1 小时前
《@SpringBootApplication:Spring Boot的"一键启动"按钮,还是程序员的"免死金牌"?》
java·后端·spring
triticale1 小时前
P12167 [蓝桥杯 2025 省 C/Python A] 倒水
java·蓝桥杯
-曾牛1 小时前
Spring AI 快速入门:从环境搭建到核心组件集成
java·人工智能·spring·ai·大模型·spring ai·开发环境搭建
啊松同学1 小时前
【Mybatis】MyBatisPlus的saveBatch真的是批量插入吗?深度解析与性能优化
java·后端·性能优化·mybatis