【Java 数据结构】二叉树的遍历 (递归和非递归实现)

news2024/11/17 21:46:19

🎉🎉🎉点进来你就是我的人了
博主主页:🙈🙈🙈戳一戳,欢迎大佬指点!

人生格言:当你的才华撑不起你的野心的时候,你就应该静下心来学习!

欢迎志同道合的朋友一起加油喔🦾🦾🦾
目标梦想:进大厂,立志成为一个牛掰的Java程序猿,虽然现在还是一个🐒嘿嘿
谢谢你这么帅气美丽还给我点赞!比个心


目录

1.二叉树前序遍历

非递归思路:

遍历递归思路:在方法的外面new ,遇到合适的元素结点就给进放

子问题思路:将左边遍历完放进去,再遍历右边完放进去,也就是大问题变小问题

2.二叉树中序遍历

非递归思路:这道题与前面那道题相似,也是用栈实现,只是访问根节点的时机不同

遍历递归思路:在方法的外面new ,遇到合适的元素结点就给进放

子问题思路:

2.二叉树后序遍历

非递归思路:也是用栈实现,注意每次添加完一个结点后需要记录一下​编辑

遍历递归

子问题思路:



1.二叉树前序遍历

写题链接:力扣

非递归思路:

递归的执行时的函数栈帧就是递出去再回退, 如果要模拟递归, 一般情况下都是使用栈, 前序遍历(根, 左, 右)二叉树的非递归实现就是, 没有递归就只能用利用while循环

按照前线遍历的思路,在循环里头先添加根结点,然后不断往左遍历,直到左树为空,再继续遍历右树。从添加左树转为右树时,有个难点,右树可能为空,也可能不为空,如果右树为空,循环就直接结束了,我们没办法遍历剩下的元素了,所以我们需要要在外层再套上一个循环,当栈不为空时,从栈里面弹出一个元素继续遍历.

1.cur == null,如果栈也空了,那么说明全部结点已经添加完了,如果栈不为空,就继续弹出元素 tmp,使 cur 再次指向 tmp.right;

2.cur != null,继续进内层循环,不断添加元素,进而进行判断!!

   实现代码:

public List<Integer> inorderTraversal(TreeNode root) {
        List<Integer> ret = new ArrayList<>();
        if(root == null ) return ret;
        Stack<TreeNode> stack = new Stack<>();
        TreeNode cur = root;
        while(cur != null || !stack.empty()) {
        while(cur != null) {
            stack.push(cur);
            cur = cur.left;
        } 
        TreeNode top = stack.pop();
        ret.add(top.val);
        cur = top.right;
        }
        return ret;
    }
}

遍历递归思路:在方法的外面new ,遇到合适的元素结点就给进放

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

子问题思路:将左边遍历完放进去,再遍历右边完放进去,也就是大问题变小问题

    public List<Integer> preorderTraversal(TreeNode root) {
        List<Integer> ret = new ArrayList<>();
        if(root == null) return ret;   
        ret.add(root.val);
        List<Integer> leftTree = preorderTraversal(root.left);
        ret.addAll(leftTree);
        List<Integer> rightTree = preorderTraversal(root.right);
        ret.addAll(rightTree);
        return ret;   
    }

2.二叉树中序遍历

写题链接:力扣

非递归思路:这道题与前面那道题相似,也是用栈实现,只是访问根节点的时机不同

class Solution {
    public List<Integer> inorderTraversal(TreeNode root) {
        List<Integer> ret =new ArrayList<>();
        if(root == null ) {
            return ret;
        }
        TreeNode cur = root;
        Deque<TreeNode> stack =new ArrayDeque<>();
        while(cur != null || !stack.isEmpty()){
        while(cur != null )  {
            stack.push(cur);
            cur =cur.left;
        }
        TreeNode top =stack.pop();
        ret.add(top.val);
        cur = top.right;
        }
        return ret;
    }
}

遍历递归思路:在方法的外面new ,遇到合适的元素结点就给进放

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

子问题思路:

class Solution {
    public List<Integer> inorderTraversal(TreeNode root) {
        List<Integer> ret = new ArrayList<>();
        if(root == null) return ret;   
        List<Integer> leftTree = inorderTraversal(root.left);
        ret.addAll(leftTree);
        ret.add(root.val);
        List<Integer> rightTree = inorderTraversal(root.right);
        ret.addAll(rightTree);
        return ret;   
    
    }
}

3.二叉树后序遍历

写题链接:力扣

非递归思路:也是用栈实现,注意每次添加完一个结点后需要记录一下

class Solution {
    // 主方法,实现后序遍历二叉树
    public List<Integer> postorderTraversal(TreeNode root) {
        // 创建一个 List 用于存储后序遍历的结果
        List<Integer> ret = new ArrayList<>();
        
        // 如果根节点为空,直接返回空结果
        if (root == null) return ret;
        
        // 创建一个栈用于存储待处理的节点
        Stack<TreeNode> stack = new Stack<>();
        
        // 初始化 prev 为 null,用于记录前一个访问过的节点
        TreeNode prev = null;
        
        // 初始化 cur 为 root,表示当前处理的节点
        TreeNode cur = root;
        
        // 当 cur 不为空或栈不为空时,说明还有节点需要处理
        while (cur != null || !stack.empty()) {
            // 当 cur 不为空时,将其入栈,并将 cur 指向其左孩子
            while (cur != null) {
                stack.push(cur);
                cur = cur.left;
            }
            
            // 查看栈顶元素,但不弹出
            TreeNode top = stack.peek();
            
            // 如果 top 的右孩子为空或者已经被访问过,需要弹出 top 并将其值添加到结果列表中
            if (top.right == null || top.right == prev) {
                stack.pop();
                ret.add(top.val);
                // 更新 prev 为 top,表示已访问过 top 节点
                prev = top;
            } else {
                // 如果 top 的右孩子还未被访问过,将 cur 指向 top 的右孩子
                cur = top.right;
            }
        }
        
        // 返回后序遍历的结果
        return ret;
    }
}

遍历递归

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

子问题思路:

class Solution {
    public List<Integer> postorderTraversal(TreeNode root) {
        List<Integer> ret = new ArrayList<>();
        if(root == null) return ret;   
        List<Integer> leftTree = postorderTraversal(root.left);
        ret.addAll(leftTree);
        List<Integer> rightTree = postorderTraversal(root.right);
        ret.addAll(rightTree);
        ret.add(root.val);
        return ret;   
    
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/451862.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

大数据分析查询_Impala介绍_对HDFS_Hbase直接查询_速度快_组成架构_执行原理---大数据之Impala工作笔记0001

官网的地址:Impala (apache.org)https://impala.apache.org/ https://impala.apache.org/ 官网的地址: 首先我们看一下什么是impala,可以看到Impala是cloudera公司,也就是做Hadoop付费版的公司, 提供的,基于Hive的,因为他跟hive共用元数据,meta,他可以提供对HDFS,Hbase的SQL…

好家伙,阿里新产Java性能优化(终极版),涵盖性能优化所有操作

上月公司来了一位大佬&#xff0c;入职不到一周就把公司现有项目的性能优化了一遍&#xff0c;直接给公司节省了一半的成本。 一问情况&#xff0c;才知道这位仁兄也是一路被虐过来的。去年年底被裁&#xff0c;本以为自己技术还行&#xff0c;看了一段时间面经&#xff0c;复…

dB 、dBSPL、dBFS、dBTP

本文整理自&#xff1a;https://corychu.medium.com/%E9%8C%84%E9%9F%B3%E7%AD%86%E8%A8%98-%E6%95%B8%E4%BD%8D%E9%9F%B3%E9%87%8F%E6%A8%99%E6%BA%96-dbfs-dbtp-lufs-c47ca4646b7f 概述&#xff1a;dBFS&#xff08;相对于满刻度的分贝&#xff09;是数字系统中振幅水平的测…

8. 优先队列

8. 优先队列 普通的队列是一种先进先出的数据结构&#xff0c;元素在队列尾追加&#xff0c;而从队列头删除。在某些情况下&#xff0c;我们可能需要找出队列中的最大值或者最小值&#xff0c;例如使用一个队列保存计算机的任务&#xff0c;一般情况下计算机的任务都是有优先级…

element select改成成tree树状下拉

<template><el-select class"jhx-formData-inputRow" ref"configSelect" v-model"orgName" filterable placeholder"请选择":filter-method"filterMethod" clear><el-option :label"orgValue.label&quo…

Redis7中的持久化技术RDB和AOF的详细解释说明

文章目录 前置知识持久化原理RDB持久化RDB优化配置项RDB文件格式RDB持久化过程RDB总结 AOF持久化AOF的工作流程AOF中的rewirte机制rewrite AOF文件格式查看AOF文件 AOF优化配置项 AOFRDB混用纯缓存模式对比和技术选型建议 前置知识 官网关于持久化的说明 Redis 是一个内存数据…

频域抽取FFT(DIF-FFT)的C语言实现

原理 此处以基2频域抽取FFT为例&#xff0c;讲述频域抽取FFT的原理。假设FFT的长度为 N 2 m N2^m N2m&#xff0c;我们将序列 x x x的FFT变换分为以下两个部分&#xff1a; X ( k ) ∑ n 0 N / 2 − 1 x ( n ) W N n k ∑ n N / 2 N − 1 x ( n ) W N n k X(k)\sum_{n0}…

SQL Server存储过程(数据库引擎)使用详解

存储过程&#xff08;数据库引擎&#xff09; 一、背景知识1.1、使用存储过程的好处1.2、存储过程的类型 二、创建存储过程三、修改存储过程四、删除存储过程五、执行存储过程5.1、建议5.2、使用 Transact-SQL执行存储过程 六、授予对存储过程的权限6.1、授予对存储过程的权限6…

院士联合指导+超强专家阵容+丰厚奖金机会,第十二届“麒麟杯”大赛报名正式开启!

当前&#xff0c;开放、协作、共享的开源模式已成为全球软件技术和产业创新的主导&#xff0c;也为信息技术国产自主化提供了强大助力。高校师生作为国产开源建设的主要技术群体之一&#xff0c;是国产开源未来发展的中坚力量。 2023年第十二届“麒麟杯”全国开源应用软件开发…

强制变成Android的形状,iPhone这波更新严重违背祖训

众所周知&#xff0c;苹果每年要开两次发布会。 秋季发布会的主角是新 iPhone &#xff0c;而6月的 WWDC 全球开发者大会则会以软件为主。 WWDC 2023 将于6月5日举行&#xff0c;iOS 17、macOS 14 及新版本 tvOS、WatchOS 都将发布。 同时新的混合现实设备所搭载的 xrOS 也有…

创建Windows 11恢复U盘的两种方法

我们在使用电脑的过程中&#xff0c;无法预知未来会出现什么问题。当您遇到一些严重的系统问题时&#xff0c;您可能需要从故障的计算机中恢复。不幸的是&#xff0c;对于大多数用户来说&#xff0c;这意味着从头开始&#xff0c;因为他们没有提前创建恢复媒体。 虽然Windows 1…

每日学术速递4.20

CV - 计算机视觉 | ML - 机器学习 | RL - 强化学习 | NLP 自然语言处理 Subjects: cs.CV 1.Avatars Grow Legs: Generating Smooth Human Motion from Sparse Tracking Inputs with Diffusion Model(CVPR 2023) 标题&#xff1a;化身长腿&#xff1a;使用扩散模型从稀疏跟踪…

知识蒸馏之自蒸馏【附代码】

知识蒸馏的核心思想就是将大模型的知识传给小模型。 这里的知识通常就是模型所学的数据分布。大模型特点一般是具有非常高的精度&#xff0c;但可能在速度上不行&#xff0c;或者是不易部署&#xff0c;小模型通常是易部署&#xff0c;速度快但精度不如大模型。 因此可以将大…

【程序员面试金典】面试题 02.07. 链表相交

【程序员面试金典】面试题 02.07. 链表相交 题目描述解题思路 题目描述 描述&#xff1a;给你两个单链表的头节点 headA 和 headB &#xff0c;请你找出并返回两个单链表相交的起始节点。如果两个链表没有交点&#xff0c;返回 null 。 图示两个链表在节点 c1 开始相交&#…

使用Storm proxies动态代理IP浅析影响在线代理IP质量的因素?

影响在线代理IP质量的因素有很多&#xff0c;主要包括以下几个方面&#xff1a; 服务器稳定性&#xff1a;在线代理IP的稳定性和可用性与其所在的服务器质量密切相关。如果服务器配置低、网络不稳定、带宽不足等因素&#xff0c;都可能导致在线代理IP的质量下降。IP地址的稳定性…

【LeetCode】剑指 Offer 66. 构建乘积数组 p312 -- Java Version

题目链接&#xff1a;https://leetcode.cn/problems/gou-jian-cheng-ji-shu-zu-lcof/ 1. 题目介绍&#xff08;66. 构建乘积数组&#xff09; 给定一个数组 A[0,1,…,n-1]&#xff0c;请构建一个数组 B[0,1,…,n-1]&#xff0c;其中 B[i] 的值是数组 A 中除了下标 i 以外的元素…

5.1.1树的定义,基本术语及性质

空树&#xff1a;结点数为0的树 除了根节点外&#xff0c;任何一个结点都有且仅有一个前驱。 子树也可看成一个新的树 所以树其实是一个递归结构 树形逻辑结构的应用 下面我们来看树的基本术语 1.节点之间的关系描述 F是你的兄弟结点&#xff0c;GHIJ就是你的堂兄弟结点。 还…

海信激光电视将亮相中国家电及消费电子博览会 科技定义家庭观影

4月27日至30日,中国家电及消费电子博览会(简称AWE)将在上海新国际博览中心举办。本届AWE强势回归,展馆规模扩大至14个,展示面积超过16万平方米,将吸引超过1200家国内外企业参展,参观人次预计将突破40万。 作为亚洲规模最大的国际家电及消费电子展览会,本届AWE以“智科技,创未来…

设计模式简介及面向对象设计原则

文章目录 前言一、什么是设计模式1、从面向对象谈起2、深入理解面向对象3、软件设计固有的复杂性4、软件设计复杂的根本原因——“变化”5、如何解决复杂性&#xff1f;6、软件设计的目标 二、常用设计模式及分类1、常用的七种设计模式2、设计模式分类 三、面向对象设计原则1、…

半导体封装用除泡烤箱真空压力可编程PID控制的解决方案

摘要&#xff1a;真空压力除泡机和除泡烤箱在电子行业的应用十分广泛&#xff0c;但现有除泡机存在的最大问题是选择了开关式阀门&#xff0c;无法实现真空和压力既准确又快速的控制。为此&#xff0c;本文提出了升级改造技术方案&#xff0c;即采用双向PID控制器和快速电动球阀…