算法-二叉树-简单-二叉树的遍历

news2024/11/24 14:56:44

记录一下算法题的学习6

首先我们要回忆一下怎么样遍历一个树:

三种遍历概念

  • 先序遍历:先访问根节点,再访问左子树,最后访问右子树。
  • 后序遍历:先左子树,再右子树,最后根节点。
  • 中序遍历:先左子树,再根节点,最后右子树。
  • 每一个子树遍历时依然按照此时的遍历顺序。

leetCode算法简单题目:

题目:给定一个二叉树的根节点 root ,返回 它的 中序 遍历 

代码与思路分析:

真香递归代码展示:
/**
  *二叉树的中序遍历 先左子树,再根节点,最后右子树。
  */
class Solution {
    public List<Integer> inorderTraversal(TreeNode root) {
      List<Integer> tree = new ArrayList<Integer>();
        inorder(root, tree);
        return tree;
    }

    public void inorder(TreeNode root, List<Integer> tree) {
        if (root == null) {
            return;
        }
     //中序遍历 定义 inorder(root) 表示当前遍历到 root\textit{root}root 节点
     //inorder(root.left) 来遍历 root 节点的左子树
     inorder(root.left, tree);
     //然后将root 节点的值加入答案
     tree.add(root.val);
     //inorder(root.right) 来遍历 root 节点的右子树
     inorder(root.right, tree);
     
    }

}
 栈与迭代代码展示:

这里我们要了解栈的特点:先进后出,后进先出

  •  先序遍历,出栈顺序:根左右; 入栈顺序:右左根
  •  中序遍历,出栈顺序:左根右; 入栈顺序:右根左
  •  后序遍历,出栈顺序:左右根; 入栈顺序:根右左
class Solution {
    public List<Integer> inorderTraversal(TreeNode root) {
        List<Integer> tree = new ArrayList<Integer>(); //定义一个遍历后的二叉树列表
  
        Deque<TreeNode> stack = new LinkedList<TreeNode>();//定义栈
        //root为空并且stack为空,遍历就会结束
        while (root != null || !stack.isEmpty()) {
           // 满足上面条件 ,先根后左入栈
            while (root != null) {
                stack.addFirst(root); //addFirst(e)等价于 push(e),
                root = root.left;
            }
            //这里仔细分析
            // 如果这里root==null,说明上一步的root没有左子树
            // 1. 执行左出栈。因为此时root==null,导致root.right一定为null(左子树里的右,可能有点混,仔细想想)
            // 2. 执行下一次外层while代码块,根出栈。此时root.right可能存在(这里是根节点的右子树)
            // 3a. 若root.right存在,右入栈,再出栈
            // 3b. 若root.right不存在,重复步骤2执行下一次外层while代码块,即root为空并且stack为空,遍历就会结束
            root = stack.removeFirst(); //1.removeFirst()等价于pop()
            tree.add(root.val);//左子树遍历完,直接将根节点添加上去
            root = root.right; //然后右子树
        }
        return tree;
    }
 }

这里我事先并不知道Deque是什么,查了一下资料,在这里简单做个记录:

Deque是一个双端队列接口,继承自Queue接口,Deque的实现类是LinkedList、ArrayDeque、LinkedBlockingDeque,其中LinkedList是最常用的。

它有三种用途:a.普通队列(一端进一端出),b.双端队列(两端都可以进出),

c.堆栈Deque deque = new LinkedList()

我们在这里使用的就是堆栈,Deque堆栈操作方法:push()、pop()、peek()。下面代码会用到。

双端队列用作 LIFO(后进先出)堆栈。应优先使用此Deque接口而不是遗留 Stack 类。在将双端队列用作堆栈时,元素被推入双端队列的开头并从双端队列开头弹出。

堆栈方法完全等效于Deque 方法

堆栈方法等效Deque方法
push(e)addFirst(e)
pop()removeFirst()
peek()peekFirst()

这里展示二叉树的前序遍历:

class Solution {
    public List<Integer> preorderTraversal(TreeNode root) {
        List<Integer> tree  = new ArrayList<Integer>();
         Deque<TreeNode> stack = new LinkedList<TreeNode>();

        if (root == null) {
            return tree;
        }
        while (!stack.isEmpty() || root != null) {
            while (root != null) {
                tree.add(root.val);
                stack.addFirst(root);
                root = root.left;
            }
            root = stack.removeFirst();
            root = root.right;
        }
        return tree;
    }


}

这里展示二叉树的后序遍历(提示:这是我看到的leedcode中对官方代码最清晰的解释):

class Solution {
    public List<Integer> postorderTraversal(TreeNode root) {
        List<Integer> tree = new ArrayList<Integer>();
        Deque<TreeNode> stack = new LinkedList<TreeNode>();

           if (root == null) {
            return tree;
        }
        //在后序遍历中,我们使用一个prev来记录历史访问记录
        //回溯到父节点时,可以由此来判断,上一个访问的节点是否为右子树
        TreeNode prev = null;
        while (root != null || !stack.isEmpty()) {
            while (root != null) {
                stack.push(root);
                root = root.left;
            }
            //从栈中弹出左子树‘先进后出’ 左子树访问完毕
            root = stack.pop();
            //现在要确定的是是否有右子树,或者右子树是否访问过
            //如果没有右子树,或者右子树访问完了,也就是上一个访问的节点是右子节点时
            //说明可以访问当前节点
            if (root.right == null || root.right == prev) {
                tree.add(root.val);
                //更新历史访问记录,这样回溯的时候父节点可以由此判断右子树是否访问完成
                prev = root;
                root = null;
            } else {
                //如果右子树没有被访问,那么将当前节点压栈,访问右子树
                stack.push(root);
                root = root.right;
            }
        }
        return tree;
    }
}

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

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

相关文章

常见的近似算法

前言 最近有个项目要用到近似算法&#xff0c;就到处摸了下&#xff0c;整理了一个小结。 近似算法统计 在Java中&#xff0c;你可以使用各种近似算法来解决不精确但接近于最优解的问题。以下是几种常见的近似算法的实现方法&#xff1a; 贪心算法&#xff08;Greedy Algori…

常见的反爬+文字加解密

一、常见的反爬介绍 基于身份识别的反爬&#xff1a;1.User-agent 2.Referer 3.Captcha 验证码 4.必备参数 基于爬虫行为的反爬&#xff1a;1.单位时间内请求数量超过一定阈值 2.相邻两次请求之间间隔小于一定阈值3.蜜罐陷阱 通过对数据加密进行反爬&#xff1a;1.对文字加密…

记录联系ThinkPad T490扬声器无声音但插耳机有声音的解决办法

型号&#xff1a;联想ThinkPad T490&#xff0c;系统Win10 64位。 现象&#xff1a;扬声器无声音&#xff0c;插耳机有声音。且右下角小喇叭正常&#xff0c;设备管理器中驱动显示一切也都正常&#xff08;无黄色小叹号&#xff09;。 解决办法&#xff1a; 尝试了各种方法&a…

【机器学习Python实战】logistic回归

&#x1f680;个人主页&#xff1a;为梦而生~ 关注我一起学习吧&#xff01; &#x1f4a1;专栏&#xff1a;机器学习python实战 欢迎订阅&#xff01;后面的内容会越来越有意思~ ⭐内容说明&#xff1a;本专栏主要针对机器学习专栏的基础内容进行python的实现&#xff0c;部分…

带你快速掌握Linux最常用的命令(图文详解)- 最新版(面试笔试常考)

最常用的Linux指令&#xff08;图文详解&#xff09;- 最新版 ls&#xff1a;列出目录中的文件和子目录。&#xff08;重点&#xff09;cd&#xff1a;改变当前工作目录。绝对路径&#xff1a;相对路径 pwd&#xff1a;显示当前工作目录的路径。mkdir&#xff1a;创建一个新的目…

盘点60个Python各行各业管理系统源码Python爱好者不容错过

盘点60个Python各行各业管理系统源码Python爱好者不容错过 学习知识费力气&#xff0c;收集整理更不易。 知识付费甚欢喜&#xff0c;为咱码农谋福利。 源码下载链接&#xff1a;https://pan.baidu.com/s/1VdAFp4P0mtWmsA158oC-aA?pwd8888 提取码&#xff1a;8888 项目名…

c语言-浅谈指针(3)

文章目录 1.字符指针变量常见的字符指针初始化另一种字符指针初始化例&#xff1a; 2.数组指针变量什么是数组指针变量数组指针变量创建数组指针变量初始化例&#xff08;二维数组传参的本质&#xff09; 3.函数指针变量什么是函数指针变量呢&#xff1f;函数指针变量创建函数指…

C语言基本算法----冒泡排序

原理 冒泡排序就是对一个存放N个数据的数组进行N次扫描&#xff0c;每次把最小或者最大的那个元素放到数组的最后&#xff0c;达到排序的目的。 原理图解 冒泡排序过程分析 冒泡排序的执行过程 冒泡排序总结 在此感谢 冒泡排序法_哔哩哔哩_bilibili 这篇blog是对这位up此视…

二维码智慧门牌管理系统升级解决方案:门牌聚合,让管理更便捷!

文章目录 前言一、传统门牌管理系统的瓶颈二、地图门牌聚合展示的优势三、地图门牌聚合展示的实现方法四、智慧门牌管理系统的未来发展 前言 随着城市的发展和建设&#xff0c;对于地址信息的管理变得越来越重要。而智慧门牌管理系统作为管理地址信息的重要工具&#xff0c;其…

Linux--网络概念

1.什么是网络 1.1 如何看待计算机 我们知道&#xff0c;对于计算机来说&#xff0c;计算机是遵循冯诺依曼体系结构的&#xff08;即把数据从外设移动到内存&#xff0c;再从内存到CPU进行计算&#xff0c;然后返回内存&#xff0c;重新读写到外设中&#xff09;。这是一台计算机…

机器人走迷宫问题

题目 1.房间有XY的方格组成&#xff0c;例如下图为64的大小。每一个方格以坐标(x,y) 描述。 2.机器人固定从方格(0, 0)出发&#xff0c;只能向东或者向北前进&#xff0c;出口固定为房间的最东北角&#xff0c;如下图的 方格(5,3)。用例保证机器人可以从入口走到出口。 3.房间…

英伟达AI布局的新动向:H200 GPU开启生成式AI的新纪元

英伟达Nvidia是全球领先的AI计算平台和GPU制造商&#xff0c;近年来一直在不断推出创新的AI产品和解决方案&#xff0c;为各行各业的AI应用提供强大的支持。 最近&#xff0c;英伟达在GTC 2023大会上发布了一款专为训练和部署生成式AI模型的图形处理单元&#xff08;GPU&#…

如何实现用户未登录不可访问系统

在开发web系统时&#xff0c;如果用户不登录&#xff0c;发现用户也可以直接正常访问系统&#xff0c;这种设计本身并不合理&#xff0c;那么我们希望看到的效果是&#xff0c;只有用户登录成功之后才可以正常访问系统&#xff0c;如果没有登录则拒绝访问。那么我们可以使用过滤…

回溯算法(3)--n皇后问题及回溯法相关习题

一、n皇后问题 1、概述 n皇后要求在一个nn的棋盘上放置n个皇后&#xff0c;使得他们彼此不受攻击&#xff0c;皇后可以攻击同一行、同一列、同一斜线上的敌人&#xff0c;所以n皇后问题要求寻找在棋盘上放置这n个皇后的方案&#xff0c;使得任意两个皇后都不在同一行、同一列或…

口袋参谋:一键下载任意买家秀图片、视频,是怎么做到的!

​对于淘宝商家来说&#xff0c;淘宝买家秀是非常的重要的。买家秀特别好看的话&#xff0c;对于提升商品的销量来说&#xff0c;会有一定的帮助&#xff0c;如何下载别人的买家秀图片&#xff0c;然后用到自己的店铺中呢&#xff1f; 这里我可以教叫你们一个办法&#xff01;那…

ROS基础—关于参数服务器的操作

1、rosparam list 获取参数服务器的所有参数。 2、rosparam get /run_id 获取参数的值

【uniapp】使用扫码插件,解决uni.scanCode扫码效率低的问题

1. 背景 uniapp 中自带的二维码扫描的 API 是 uni.scanCode&#xff0c;但有如下问题&#xff1a; 二维码扫描的效率不高&#xff0c;有些需要扫2秒左右 较小或模糊的一些二维码无法识别出来&#xff0c;多次扫同样的一个码可能出现扫码失败的情况 受环境影响大&#xff0c…

腾讯云服务器怎么买便宜?腾讯云服务器新人专享限时特惠购买链接

腾讯云作为国内领先的云计算服务提供商之一&#xff0c;为个人用户和企业用户提供了多种优惠活动。这些活动不仅能帮助用户节省成本&#xff0c;还能提升企业的效益。本文将介绍腾讯云的多重优惠活动&#xff0c;让用户能够以更优惠的价格购买和续费云服务器。 腾讯云双十一领…

动手学深度学习——循环神经网络的简洁实现(代码详解)

文章目录 循环神经网络的简洁实现1. 定义模型2. 训练与预测 循环神经网络的简洁实现 # 使用深度学习框架的高级API提供的函数更有效地实现相同的语言模型 import torch from torch import nn from torch.nn import functional as F from d2l import torch as d2lbatch_size, …

解决docker运行elastic服务端启动不成功

现象&#xff1a; 然后查看docker日志&#xff0c;发现有vm.max_map_count报错 ERROR: [1] bootstrap checks failed [1]: max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144] 解决办法&#xff1a; 1. 宿主机&#xff08;运行doc…