首页 > 其他分享 >刷刷刷 Day 14| 二叉树的遍历

刷刷刷 Day 14| 二叉树的遍历

时间:2023-01-20 17:56:13浏览次数:58  
标签:node 遍历 14 res Day 二叉树 null root 节点

144. 二叉树的前序遍历

LeetCode题目要求

给你二叉树的根节点 root ,返回它节点值的 前序 遍历。
示例

图
输入:root = [1,null,2,3]
输出:[1,2,3]
解题思路

最重要的要明白什么是二叉树的前序遍历:即从中间节点开始到左节点再到右节点的遍历过程,可简称为【中左右】遍历
如下图标识的遍历过程,在过程中下面指向的 null ,就是说明到子节点了,如果这是我们知道左节点到了子节点,那就要从右节点开始。

图

上代码,递归实现

class Solution {

    public List<Integer> preorderTraversal(TreeNode root) {
        // 前序遍历即:从中间节点开始到左节点再到右节点的遍历过程,可简称为【中左右】遍历
        
        // 用 List 来存储遍历的结果
        List<Integer> res = new ArrayList<>();
        preorder(root, res);

        return res;
    }

    public void preorder(TreeNode curr, List<Integer> res) {
        // 1、先拿中节点,
        // 2、判断左节点,如果左不为空,那么又作为新的中节点,重复 1、2,直到节点为空
        // 3、判断右节点,如果右不为空,那么又作为新的中节点,重复 1、3,直到节点为空

        if (curr == null) {
            return;
        }

        res.add(curr.val);
        preorder(curr.left, res);
        preorder(curr.right, res);
    }
}

上代码,迭代实现

class Solution {

    public List<Integer> preorderTraversal(TreeNode root) {
        List<Integer> res = new ArrayList<>();

        if (root == null) {
            return res;
        }

        // 通过栈来实现,将二叉树的以 中右左的顺序 压入栈中,出栈时的顺序才是中左右 
        Deque<TreeNode> stack = new ArrayDeque<>();
        stack.push(root);

        // 开始遍历栈,如果栈不为空,就先出栈
        while (!stack.isEmpty()) {
            TreeNode curr = stack.pop();
            res.add(curr.val);

            if (curr.right != null) stack.push(curr.right);
            if (curr.left != null) stack.push(curr.left);
        }
        return res;
    }
}

145. 二叉树的后序遍历

LeetCode题目要求

给你一棵二叉树的根节点 root ,返回其节点值的 后序遍历 。
示例

图
输入:root = [1,null,2,3]
输出:[3,2,1]
解题思路

最重要的要明白什么是二叉树的后序遍历:即从左节点开始到右节点再到中间节点的遍历过程,可简称为【左右中】遍历
如下图标识的遍历过程,总是从最左节点开始的。

图

上代码,递归实现

class Solution {
    public List<Integer> postorderTraversal(TreeNode root) {
        // 存储结果
        List<Integer> res = new ArrayList<>();
        postorder(root, res);
        return res;
    }

    public void postorder(TreeNode node, List<Integer> res) {
        if (node == null) {
            return;
        }

        // 从左节点开始递归,这里从root 开始一直到最左子节点,才能继续找右节点,但是右节点为空,那么就把当前左节点的值放入结果
        postorder(node.left, res);
        // 从右节点开始递归
        postorder(node.right, res);
        // 将当前节点值放入结果集
        res.add(node.val);
    }
}

上代码,迭代实现

class Solution {

    public List<Integer> postorderTraversal(TreeNode root) {
        List<Integer> res = new ArrayList<>();

        if (root == null) {
            return res;
        }

        Deque<TreeNode> stack = new ArrayDeque<>();
         
        // 后序遍历: 左右中,  前序遍历的顺序是 中左右,
        // 那么可以在入栈时调整顺序变成 中左右,出栈顺序为 中右左, 然后再反转结果就是我们需要的
        stack.push(root);

        while (!stack.isEmpty()) {
            TreeNode node = stack.pop();
            res.add(node.val);
            if (node.left != null) stack.push(node.left);
            if (node.right != null) stack.push(node.right);
        }

        Collections.reverse(res);
        return res;
    }
}

94. 二叉树的中序遍历

LeetCode题目要求

给定一个二叉树的根节点 root ,返回 它的 中序 遍历 。
示例

图
输入:root = [1,null,2,3]
输出:[1,3,2]
解题思路

最重要的要明白什么是二叉树的中序遍历:即从左节点开始到中间节点再到右节点的遍历过程,可简称为【左中右】遍历
如下图标识的遍历过程,总是从最左节点开始的。

图

上代码,递归实现

class Solution {

    public List<Integer> inorderTraversal(TreeNode root) {
        List<Integer> res = new ArrayList<>();
        inorder(root, res);
        return res;
    }

    public void inorder(TreeNode node, List<Integer> res) {
        if (node == null) {
            return;
        }
        // 左中右
        inorder(node.left, res);
        res.add(node.val);
        inorder(node.right, res);
    }
}

上代码,迭代实现

class Solution {
    public List<Integer> inorderTraversal(TreeNode root) {
        List<Integer> res = new ArrayList<>();
        if (root == null) {
            return res;
        }

        Deque<TreeNode> stack = new ArrayDeque<>();
        TreeNode node = root;
        while (node != null || !stack.isEmpty()) {
            // 中序遍历的为 左中右,使用栈时,入栈时,从根一直遍历左节点,都入栈
            if (node != null) {
                stack.push(node);
                node = node.left;
            } else {
                // 当上面的操作左节点都入栈后,此时栈不为空,开始出栈操作,就是左节点出栈并将其值入结果集,同时取右节点
                node = stack.pop();
                res.add(node.val);
                node = node.right;
            }
        }

        return res;
    }
}
重难点

对于递归遍历来说,遍历二叉树代码写起来比较容易,但是递归的过程需要重点理解下。
而对于迭代法来说,弄明白入栈与出栈的过程就基本可以明白,可以通过模拟过程来理解,而中序遍历与前、后序遍历不太一样,需要着重理解了。

附:学习资料链接

标签:node,遍历,14,res,Day,二叉树,null,root,节点
From: https://www.cnblogs.com/blacksonny/p/17062956.html

相关文章

  • 2023WinterHoliday刷题总结第一弹
    \(2023WinterHoliday\)刷题总结第一弹\(CTF\)\(Web\)1.\(json格式:\)$json['x']=="wllm"\(JSON\)(JavaScriptObjectNotation,JS对象简谱)是一种轻量级的数据交换格式,采......
  • 树,森林与二叉树的转换复习
    普通的树,结构太多,研究起来也很复杂。但是依据树的孩子兄弟表示法,可以将普通的树,转换为二叉树,就方便很多。转换步骤:1,加线:在所有兄弟之间连线2,去线:对树中每个结点,只保留它......
  • 线索二叉树
    线索二叉树的实现内涵,一棵n个结点的树中一定会存在n+1个空指针域,将此指针域给利用起来,实现指向前驱或后继。其线索二叉树,等于把一颗二叉树转化为一个双向链表。对二叉树......
  • 二叉树的最大宽度--google面试遇到过,他是要求求解所有路径path
    543.二叉树的直径难度简单1221收藏分享切换为英文接收动态反馈给定一棵二叉树,你需要计算它的直径长度。一棵二叉树的直径长度是任意两个结点路径长度中的最大值。......
  • 【DFS】LeetCode 951. 翻转等价二叉树
    题目链接951.翻转等价二叉树思路如果二叉树root1,root2根节点值相等,那么只需要检查他们的孩子是不是相等就可以了。如果root1或者root2是null,那么只有在他们都......
  • 代码随想录算法训练营day09 | leetcode 28. 实现 strStr()
    LeetCode28.实现strStr()牢记一点:next[i]元素表示【0,i】子串的最长相等前后缀个数,也是模式串与主串匹配不相等时模式串的下一个比较索引分析1.0前缀是指不包含最后......
  • 「解题报告」ARC141E Sliding Edge on Torus
    这题为啥能上3000,我这种废物都能一眼看出来做法...首先发现可以将点根据\(x-y\)的值分成\(n\)组,第\(x\)组的第\(i\)个点为\((i,i+x)\),这样每次连边的时候......
  • 【DFS】LeetCode 101. 对称二叉树
    题目链接101.对称二叉树思路DFS递归解决代码classSolution{publicbooleanisSymmetric(TreeNoderoot){if(root==null){returnt......
  • 《RPC实战与核心原理》学习笔记Day3
    04|网络通信:RPC框架在网络通信上更倾向于哪种网络IO模型?网络通信在RPC调用中有什么作用?RPC是解决进程间通信的一种方式,一次RPC调用,本质就是服务消费者与服务提供者之......
  • day7--哈希表--四数相加
     1.四数相加lettcode454我的想法使用暴力解法,我写出来啦~很开心,但是会超时,时间复杂度太高了,这里应该是O(n^4),然后看下优化的哈希写法classSolution{public:int......