【蓝桥Java每日一练】————6.二叉树的前中后序遍历(递归与迭代)(下)

简介: 【蓝桥Java每日一练】————6.二叉树的前中后序遍历(递归与迭代)

🍈2.迭代解法


             有兄弟肯定觉得,你递归解法只用在前序遍历的基础上改动一下即可,那你迭代解法一样改改不就行了吗?你还真别说,这样不行!因为前序是先处理中节点也就是根节点,是比较容易操作的,而我们的中序遍历是先处理左节点完后才能一个个倒退回来处理根节点。也就是说需要先将所有的左子节点放入栈后再一个个出栈,然后才能处理中节点和右节点。


class Solution {
    List<Integer> list=new ArrayList<>();
    Deque<TreeNode> Stack=new ArrayDeque<>();
    public List<Integer> inorderTraversal(TreeNode root) {
           while(root!=null||!Stack.isEmpty()){
               //一个while循环把左节点疯狂放入到栈中
               while(root!=null){
                   Stack.push(root);
                   root=root.left;
               }
               //最下面的左子节点出栈,获取他
               root=Stack.pop();
               //加入list中
               list.add(root.val);
               //去处理右节点
               root=root.right;
           }
           return list;
    }
}


        我自己觉得这串代码刚开始还是有点难理解的,光说也是很难理解的,但是如果大家能用草稿纸自己画个栈debug一下,就能非常快的理解,还是希望大家开发一下动手能力多多理解。


🍍3.二叉树的后序遍历(左右中)


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


题目链接:二叉树的后序遍历https://leetcode-cn.com/problems/binary-tree-postorder-traversal/


🍍1.递归解法


还是熟悉的配方还是熟悉的味道,换个位置(递归yyds)


class Solution {
    List<Integer> list=new ArrayList<>();
    public List<Integer> postorderTraversal(TreeNode root) {
            test(root);
            return list;
    }
    public void test(TreeNode root){
        if(root==null) return;
        test(root.left);
        test(root.right);
        list.add(root.val);     
    }
}

🍍2.迭代解法


              后序的迭代就比较有趣了,我们都知道我们写了前序的遍历顺序是中左右,在里面我们有个入栈的步骤,是先入右再入左,如果我们先入左再入右是不是遍历顺序就是中右左,这时我们把得到的答案list整个反过来,是不是就变成了左右中,也就是我们的后序遍历了。大家对比一下代码就能发现很神奇了!


image.png

class Solution {
    //用来存放答案的list
    List<Integer> list=new ArrayList<>();
    //用来当栈
    Deque<TreeNode> statck=new ArrayDeque<>();
    public List<Integer> postorderTraversal(TreeNode root) {
        if(root==null) return list;
        statck.push(root);
        while(!statck.isEmpty()){
            TreeNode node=statck.pop();
            list.add(node.val);
            //先放左再放右
            if(node.left!=null){
                statck.push(node.left);
            }
            if(node.right!=null){
                statck.push(node.right);
            } 
        }
        //反转链表
        Collections.reverse(list);
        return list;
    }
}


🍋4.关于递归以及迭代的看法


        看到这里肯定很多兄弟觉得,那我学个递归不就行了吗,又不用变化又简单。但其实这是不对的,如果你真的理解了递归的思想,那你也是可以写出迭代的做法,如果不能,那只能说明你在生搬硬套公式而已。在现在的面试中,涉及到这类题目,面试官都回要求使用迭代的做法,因为他知道你如果能写出迭代,递归也难不倒你。所以希望兄弟们一定要掌握号迭代的做法,真正去掌握二叉树的遍历能力,去分析三者的不同。


相关文章
|
1月前
|
存储 Java
Java学习笔记 List集合的定义、集合的遍历、迭代器的使用
Java学习笔记 List集合的定义、集合的遍历、迭代器的使用
|
1月前
|
Java 容器
07 Java数组与数组操作(定义+遍历+排序+增删改查)(上)
07 Java数组与数组操作(定义+遍历+排序+增删改查)
33 8
|
1月前
|
存储 Java API
07 Java数组与数组操作(定义+遍历+排序+增删改查)(下)
07 Java数组与数组操作(定义+遍历+排序+增删改查)
29 4
|
1月前
|
存储 算法 Java
LeetCode经典算法题:二叉树遍历(递归遍历+迭代遍历+层序遍历)以及线索二叉树java详解
LeetCode经典算法题:二叉树遍历(递归遍历+迭代遍历+层序遍历)以及线索二叉树java详解
60 0
|
3月前
|
缓存 Java 测试技术
探讨Java中遍历Map集合的最快方式
探讨Java中遍历Map集合的最快方式
41 1
|
3月前
|
存储 缓存 Java
Java遍历Map集合的方法
在Java中,遍历Map集合主要有四种方式:1) 使用`keySet()`遍历keys并用`get()`获取values;2) 使用`entrySet()`直接遍历键值对,效率较高;3) 通过`Iterator`遍历,适合在遍历中删除元素;4) Java 8及以上版本可用`forEach`和Lambda表达式,简洁易读。`entrySet()`通常性能最佳,而遍历方式的选择应考虑代码可读性和数据量。
47 0
Java 遍历Map集合的各种姿势
最常用,在键值都需要时使用。 Map map = new HashMap(); for (Map.Entry entry : map.entrySet()) { System.out.println("Key = " + entry.getKey() + ", Value = " + entry.getValue()); } 在for-each循环中遍历keys或values。
694 0
Java使用增强for循环和迭代器遍历Map集合
1、通过key集合访问,对Key敢兴趣,可以访问与key对应的Value值;  for(String k:maps.keySet()){             System.
1040 0
|
6天前
|
存储 缓存 安全
【Java面试题汇总】多线程、JUC、锁篇(2023版)
线程和进程的区别、CAS的ABA问题、AQS、哪些地方使用了CAS、怎么保证线程安全、线程同步方式、synchronized的用法及原理、Lock、volatile、线程的六个状态、ThreadLocal、线程通信方式、创建方式、两种创建线程池的方法、线程池设置合适的线程数、线程安全的集合?ConcurrentHashMap、JUC
【Java面试题汇总】多线程、JUC、锁篇(2023版)
|
17天前
|
监控 Java 调度
【Java学习】多线程&JUC万字超详解
本文详细介绍了多线程的概念和三种实现方式,还有一些常见的成员方法,CPU的调动方式,多线程的生命周期,还有线程安全问题,锁和死锁的概念,以及等待唤醒机制,阻塞队列,多线程的六种状态,线程池等
79 6
【Java学习】多线程&JUC万字超详解