【蓝桥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.关于递归以及迭代的看法


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


相关文章
|
Java
java实现遍历树形菜单方法——OpenSessionView实现
java实现遍历树形菜单方法——OpenSessionView实现
11 0
|
29天前
|
Java
java实现遍历树形菜单方法——TreeAction实现
java实现遍历树形菜单方法——TreeAction实现
9 0
|
29天前
|
Java
java实现遍历树形菜单方法——HibernateUtil实现
java实现遍历树形菜单方法——HibernateUtil实现
10 0
|
29天前
|
Java
java实现遍历树形菜单方法——service层
java实现遍历树形菜单方法——service层
10 0
|
Java
java实现遍历树形菜单方法——index.jsp实现
java实现遍历树形菜单方法——index.jsp实现
6 0
|
算法 Java 程序员
Java数据结构与算法——递归与回溯
Java数据结构与算法——递归与回溯
Java数据结构与算法——递归与回溯
|
9天前
|
存储 Java 数据库连接
java多线程之线程通信
java多线程之线程通信
|
10天前
|
安全 Java 开发者
深入理解Java并发编程:线程安全与性能优化
【4月更文挑战第9天】本文将深入探讨Java并发编程的核心概念,包括线程安全和性能优化。我们将详细解析Java中的同步机制,包括synchronized关键字、Lock接口以及并发集合等,并探讨它们如何影响程序的性能。此外,我们还将讨论Java内存模型,以及它如何影响并发程序的行为。最后,我们将提供一些实用的并发编程技巧和最佳实践,帮助开发者编写出既线程安全又高效的Java程序。
22 3
|
11天前
|
Java
Java 并发编程:深入理解线程池
【4月更文挑战第8天】本文将深入探讨 Java 中的线程池技术,包括其工作原理、优势以及如何使用。线程池是 Java 并发编程的重要工具,它可以有效地管理和控制线程的执行,提高系统性能。通过本文的学习,读者将对线程池有更深入的理解,并能在实际开发中灵活运用。
|
9天前
|
算法 Java 开发者
Java中的多线程编程:概念、实现与性能优化
【4月更文挑战第9天】在Java编程中,多线程是一种强大的工具,它允许开发者创建并发执行的程序,提高系统的响应性和吞吐量。本文将深入探讨Java多线程的核心概念,包括线程的生命周期、线程同步机制以及线程池的使用。接着,我们将展示如何通过继承Thread类和实现Runnable接口来创建线程,并讨论各自的优缺点。此外,文章还将介绍高级主题,如死锁的预防、避免和检测,以及如何使用并发集合和原子变量来提高多线程程序的性能和安全性。最后,我们将提供一些实用的性能优化技巧,帮助开发者编写出更高效、更稳定的多线程应用程序。