【数据结构】 二叉树面试题讲解->叁

文章目录

  • 🌏引言
  • 🌲[根据二叉树创建字符串](https://leetcode.cn/problems/construct-string-from-binary-tree/submissions/)
    • 🐱‍👤题目描述:
    • 🐱‍🐉示例:
      • 📌示例一
      • 📌示例二
    • 🐱‍👓思路解析
    • 🐱‍🏍代码完整实现:
  • 🌴判断一棵树是不是完全二叉树
    • 🐱‍👤题目描述:
    • 🐱‍🐉示例:
    • 🐱‍👓思路解析:
    • 🐱‍🏍完整代码实现:
  • 🎋[二叉树的前序遍历(迭代实现)](https://leetcode.cn/problems/binary-tree-preorder-traversal/)
    • 🐱‍👤题目描述:
    • 🐱‍🐉示例:
    • 🐱‍👓思路解析:
    • 🐱‍🏍代码实现如下:
  • 🍀[二叉树的中序遍历(迭代实现)](https://leetcode.cn/problems/binary-tree-inorder-traversal/description/)
    • 🐱‍👤题目描述:
    • 🐱‍🐉示例:
    • 🐱‍👓思路解析:
    • 🐱‍🏍代码实现:
  • 🎄[二叉树的后续遍历(迭代实现)](https://leetcode.cn/problems/binary-tree-postorder-traversal/description/)
    • 🐱‍👤题目描述:
    • 🐱‍🐉示例:
    • 🐱‍👓思路解析:
    • 🐱‍🏍代码完整实现:
  • ⭕总结

🌏引言

二叉树的操作算法是笔试面试中较为常见的题目。
本文将着重介绍平时面试中常见的关于二叉树的应用题目,马上要进行秋招了。希望对你们有帮助 _😀
在这里插入图片描述

🌲根据二叉树创建字符串

🐱‍👤题目描述:

给你二叉树的根节点 root ,请你采用前序遍历的方式,将二叉树转化为一个由括号和整数组成的字符串,返回构造出的字符串。

空节点使用一对空括号对 “()” 表示,转化后需要省略所有不影响字符串与原始二叉树之间的一对一映射关系的空括号对。

/*** Definition for a binary tree node.* public class TreeNode {*     int val;*     TreeNode left;*     TreeNode right;*     TreeNode() {}*     TreeNode(int val) { this.val = val; }*     TreeNode(int val, TreeNode left, TreeNode right) {*         this.val = val;*         this.left = left;*         this.right = right;*     }* }*/
class Solution {
public String tree2str(TreeNode root) {}
}

🐱‍🐉示例:

📌示例一

在这里插入图片描述

📌示例二

在这里插入图片描述

🐱‍👓思路解析

我们可以使用递归的方法得到二叉树的前序遍历,并在递归时加上额外的括号。

会有以下 4种情况:

  • 如果当前节点有两个孩子,那我们在递归时,需要在两个孩子的结果外都加上一层括号;

  • 如果当前节点没有孩子,那我们不需要在节点后面加上任何括号;
    在这里插入图片描述

  • 如果当前节点只有左孩子,那我们在递归时,只需要在左孩子的结果外加上一层括号,而不需要给右孩子加上任何括号;

  • 在这里插入图片描述

  • 如果当前节点只有右孩子,那我们在递归时,需要先加上一层空的括号 ‘()’\text{`()'}‘()’ 表示左孩子为空,再对右孩子进行递归,并在结果外加上一层括号。

  • 在这里插入图片描述

那我们具体应该怎么做呢?

做法如下:

  • 由于我们需要返回一个字符串,我们这里创建一个StringBuilder类的对象stringbuilder来存放我们的字符串
  • 接下来我们创建一个方法tree2strChild用于遍历二叉树,并将二叉树变为字符串
  • 在tree2strChild方法里,我们首先将根节点放入到字符串stringbuilder中
  • 然后对左子树进行判断,若不为null
  • 则字符串添加一个左括号
  • 然后递归左子树
  • 递归完后添加右括号
  • 若为null,且右边不为null
  • 则字符串添加()
  • 接下来判断右子树
  • 若右子树为null
  • 直接返回就好
  • 若不为null
  • 字符串添加左括号
  • 然后递归右树
  • 追后字符串添加右括号即可

🐱‍🏍代码完整实现:

/*** Definition for a binary tree node.* public class TreeNode {*     int val;*     TreeNode left;*     TreeNode right;*     TreeNode() {}*     TreeNode(int val) { this.val = val; }*     TreeNode(int val, TreeNode left, TreeNode right) {*         this.val = val;*         this.left = left;*         this.right = right;*     }* }*/
class Solution {
public String tree2str(TreeNode root) {if(root == null) {return null;}StringBuilder stringBuilder = new StringBuilder();tree2strChild(root,stringBuilder);return stringBuilder.toString();}public void tree2strChild(TreeNode t,StringBuilder stringBuilder) {if(t == null) {return;}stringBuilder.append(t.val);if(t.left != null) {stringBuilder.append("(");tree2strChild(t.left,stringBuilder);stringBuilder.append(")");}else {//左边为空了if(t.right != null) {//右边不为空stringBuilder.append("()");}else {//右边为空return ;}}if(t.right == null) {return;}else {stringBuilder.append("(");tree2strChild(t.right,stringBuilder);stringBuilder.append(")");}}
}

🌴判断一棵树是不是完全二叉树

🐱‍👤题目描述:

给你一棵树让你判断是不是完全二叉树

🐱‍🐉示例:

在这里插入图片描述

🐱‍👓思路解析:

其实这道题与博主前面所讲的层序遍历类似

  • 我们依旧定义一个队列,先将根结点入队
  • 如果队列不为空我们就进入循环
  • 将队列的元素进行出栈并赋给cur变量
  • 如果cur不等于null,我们就将cur的左树和右树进行入队
  • 不用管左树右树是否为null;
  • 如果cur为null则跳出循环

这时候队列元素为
在这里插入图片描述
这时候我可以将队列进行出队,元素全部为null,则为完全二叉树

🐱‍🏍完整代码实现:

    boolean isCompleteTree(TreeNode root){if(root == null) {return true;}Queue<TreeNode> queue = new LinkedList<>();queue.offer(root);while (!queue.isEmpty()) {TreeNode cur = queue.poll();if(cur != null) {queue.offer(cur.left);queue.offer(cur.right);}else {break;}}while (!queue.isEmpty()) {TreeNode tmp = queue.poll();if(tmp != null) {return false;}}return true;}

🎋二叉树的前序遍历(迭代实现)

🐱‍👤题目描述:

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

/*** Definition for a binary tree node.* public class TreeNode {*     int val;*     TreeNode left;*     TreeNode right;*     TreeNode() {}*     TreeNode(int val) { this.val = val; }*     TreeNode(int val, TreeNode left, TreeNode right) {*         this.val = val;*         this.left = left;*         this.right = right;*     }* }*/
class Solution {public List<Integer> preorderTraversal(TreeNode root) {}
}

🐱‍🐉示例:

在这里插入图片描述

🐱‍👓思路解析:

我们创建一个栈来实现迭代的前序遍历

  • 我们用变量cur来进行遍历
  • 首先我们对cur进行判断,若不为null,
  • 则将cur入栈,并将该元素存储在顺序表list里
  • 然后遍历cur的左子树

将上述操作放入一个循环里,循环条件就为cur是否为null;

当cur为null时,我们就将栈中元素进行出栈赋给变量top

并用cur访问top的右子树

上面的操作我们再放入一个外循环里,条件为cur不为null或者栈不为空

🐱‍🏍代码实现如下:

/*** Definition for a binary tree node.* public class TreeNode {*     int val;*     TreeNode left;*     TreeNode right;*     TreeNode() {}*     TreeNode(int val) { this.val = val; }*     TreeNode(int val, TreeNode left, TreeNode right) {*         this.val = val;*         this.left = left;*         this.right = right;*     }* }*/
class Solution {public List<Integer> preorderTraversal(TreeNode root) {List<Integer> list = new ArrayList<>();if(root == null) {return list;}TreeNode cur = root;Deque<TreeNode> stack = new ArrayDeque<>();while (cur != null || !stack.isEmpty()) {while (cur != null) {stack.push(cur);list.add(cur.val);cur = cur.left;}TreeNode top = stack.pop();cur = top.right;}return list;}
}

🍀二叉树的中序遍历(迭代实现)

🐱‍👤题目描述:

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

/*** Definition for a binary tree node.* public class TreeNode {*     int val;*     TreeNode left;*     TreeNode right;*     TreeNode() {}*     TreeNode(int val) { this.val = val; }*     TreeNode(int val, TreeNode left, TreeNode right) {*         this.val = val;*         this.left = left;*         this.right = right;*     }* }*/
class Solution {public List<Integer> inorderTraversal(TreeNode root) {}
}

🐱‍🐉示例:

在这里插入图片描述

🐱‍👓思路解析:

与前序遍历步骤大致相同

不同的是中序遍历需要先在顺序表内存储左节点

也就是说我们需要先将该节点的左节点全部入栈后,然后再出栈到顺序表内

接下来访问右子树

🐱‍🏍代码实现:

/*** Definition for a binary tree node.* public class TreeNode {*     int val;*     TreeNode left;*     TreeNode right;*     TreeNode() {}*     TreeNode(int val) { this.val = val; }*     TreeNode(int val, TreeNode left, TreeNode right) {*         this.val = val;*         this.left = left;*         this.right = right;*     }* }*/
class Solution {public List<Integer> inorderTraversal(TreeNode root) {List<Integer> list = new ArrayList<>();if(root == null) {return list;}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();list.add(top.val);cur = top.right;}return list;}
}

🎄二叉树的后续遍历(迭代实现)

🐱‍👤题目描述:

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

/*** Definition for a binary tree node.* public class TreeNode {*     int val;*     TreeNode left;*     TreeNode right;*     TreeNode() {}*     TreeNode(int val) { this.val = val; }*     TreeNode(int val, TreeNode left, TreeNode right) {*         this.val = val;*         this.left = left;*         this.right = right;*     }* }*/
class Solution {public List<Integer> postorderTraversal(TreeNode root) {}
}

🐱‍🐉示例:

在这里插入图片描述

🐱‍👓思路解析:

入栈思路与前序遍历和中序遍历思路相同

只是出栈不同

  • 我们首先需要得到栈顶元素,但不出栈,依旧用top表示
  • 如果top右节点为null,则说明top为叶子结点,可以出栈进入到顺序表类
  • 如果不为null,则遍历top的右节点

当然现在的思路还有一个问题,我们可能重复遍历top的右子树,最终程序崩溃

所以我们这里加一个变量pero进行判断,若相等则不再遍历该右节点

🐱‍🏍代码完整实现:

/*** Definition for a binary tree node.* public class TreeNode {*     int val;*     TreeNode left;*     TreeNode right;*     TreeNode() {}*     TreeNode(int val) { this.val = val; }*     TreeNode(int val, TreeNode left, TreeNode right) {*         this.val = val;*         this.left = left;*         this.right = right;*     }* }*/
class Solution {public List<Integer> postorderTraversal(TreeNode root) {List<Integer> list = new ArrayList<>();if(root == null) {return list;}TreeNode cur = root;TreeNode prev = null;Deque<TreeNode> stack = new ArrayDeque<>();while (cur != null || !stack.isEmpty()) {while (cur != null) {stack.push(cur);cur = cur.left;}TreeNode top = stack.peek();if(top.right == null || top.right == prev) {list.add(top.val);stack.pop();prev = top;}else {cur = top.right;}}return list;}
}

⭕总结

关于《【数据结构】 二叉树面试题讲解->叁》就讲解到这儿,感谢大家的支持,欢迎各位留言交流以及批评指正,如果文章对您有帮助或者觉得作者写的还不错可以点一下关注,点赞,收藏支持一下!

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

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

相关文章

Autofac中多个类继承同一个接口,如何注入?与抽象工厂模式相结合

多个类继承同一个接口,如何注入&#xff1f;与抽象工厂模式相结合 需求: 原来是抽象工厂模式,多个类继承同一个接口。 现在需要使用Autofac进行选择性注入。 Autofac默认常识: Autofac中多个类继承同一个接口,默认是最后一个接口注入的类。 解决方案&#xff1a;(约定大于配…

Scala的函数式编程与高阶函数,匿名函数,偏函数,函数的闭包、柯里化,抽象控制,懒加载等

Scala的函数式编程 函数式编程 解决问题时&#xff0c;将问题分解成一个一个的步骤&#xff0c;将每个步骤进行封装&#xff08;函数&#xff09;&#xff0c;通过调用这些封装好的步骤&#xff0c;解决问题。 例如&#xff1a;请求->用户名、密码->连接 JDBC->读取…

分布式session的4种解决方案

分布式session的4种解决方案 1、cookie和session cookie和session都是用来跟踪用户身份信息的会话方式。 cookie存储的数据保存在本地客户端&#xff0c;用户获取容易&#xff0c;但安全性不高&#xff0c;存储数据小。 session存储的数据保存在服务器&#xff0c;用户不易获取…

linux中busybox与文件系统的关系

busybox与文件系统 在 Linux 中&#xff0c;BusyBox 是一个精简的、多功能的工具集合&#xff0c;它包含了一系列常用的命令和实用程序&#xff0c;如 ls、cp、mkdir 等。BusyBox 的目标是提供一个功能完整而又占用空间较小的工具集合&#xff0c;适用于嵌入式系统或资源受限的…

安防监控视频平台EasyCVR视频汇聚平台定制项目增加AI智能算法详细介绍

安防视频集中存储EasyCVR视频汇聚平台&#xff0c;可支持海量视频的轻量化接入与汇聚管理。平台能提供视频存储磁盘阵列、视频监控直播、视频轮播、视频录像、云存储、回放与检索、智能告警、服务器集群、语音对讲、云台控制、电子地图、平台级联、H.265自动转码等功能。为了便…

hadoop学习:mapreduce入门案例四:partitioner 和 combiner

先简单介绍一下partitioner 和 combiner Partitioner类 用于在Map端对key进行分区 默认使用的是HashPartitioner 获取key的哈希值使用key的哈希值对Reduce任务数求模决定每条记录应该送到哪个Reducer处理自定义Partitioner 继承抽象类Partitioner&#xff0c;重写getPartiti…

udig下载、安装及汉化,生成geoserver图层样式sld文件

uDig是一款开源免费的桌面地理信息系统框架软件。uDig汉化版主要采用RCP技术构建&#xff0c;内置的多专业的水文工具&#xff0c;拥有复杂专业的分析能力&#xff0c;既可以作为独立程序运行&#xff0c;还可以作为插件使用。 uDig是一个 open source (EPL and BSD) 桌面应用程…

【高阶产品策略】设计有效的AB测试

文章目录 1、A/B测试概述2、A/B测试实施过程3、A/B测试中需要注意的地方4、从一个案例中看A/B测试 1、A/B测试概述 2、A/B测试实施过程 3、A/B测试中需要注意的地方 4、从一个案例中看A/B测试

JAVA基础-JDBC

本博客记录JAVA基础JDBC部分的学习内容 JDBC基本概念 JDBC : JAVA链接数据库&#xff0c;是JAVA链接数据库的技术的统称&#xff0c;包含如下两部分&#xff1a; 1. JAVA提供的JDBC规范&#xff08;即各种数据库接口&#xff09;存储在java.sql 和 javax.sql中的api 2. 各个数…

【小吉送书—第一期】Kali Linux高级渗透测试

文章目录 &#x1f354;前言&#x1f6f8;读者对象&#x1f388;本书资源&#x1f384;彩蛋 &#x1f354;前言 对于企业网络安全建设工作的质量保障&#xff0c;业界普遍遵循PDCA&#xff08;计划&#xff08;Plan&#xff09;、实施&#xff08;Do&#xff09;、检查&#x…

【计算机网络】HTTP

文章目录 1.HTTP概念2. URLurlencode 和 urldecode转义规则 3. HTTP的宏观理解HTTP的请求HTTP的响应 4. 见一见HTTP请求和响应请求报头 1. 模拟一个简单的响应response响应报头 2. 从路径中获取内容ReadFile函数的实现 3.不同资源进行区分反序列化的实现ReadOneLine函数的实现P…

C++异常

文章目录 C异常异常语法代码示例 栈解旋示例代码 noexcept代码示例 异常的声明周期示例代码 异常的多态使用代码示例 C标准异常库代码示例 重写自己的异常示例代码 C异常 异常是处理程序中的错误。所谓的错误时指程序运行的过程中发生的一些异常事件(如&#xff1a;除零错误&a…

百数应用中心——生产制造管理解决方案解决行业难题

传统生产制造业面临着许多挑战&#xff0c;其中一些主要问题包括效率低下、交期压力大、需求预测不准确、生产模式复杂、异常响应慢、库存高和计划脱节等。这些问题不仅影响了生产效率和质量&#xff0c;也导致了不必要的成本和客户满意度下降。 生产制造管理应用对于企业的生产…

介绍几种使用工具

FileWatch&#xff0c;观测文件变化&#xff0c;源码地址&#xff1a;https://github.com/ThomasMonkman/filewatch nlohmann::json&#xff0c;json封装解析&#xff0c;源码地址&#xff1a;https://github.com/nlohmann/json optionparser&#xff0c;解析选项&#xff0c;源…

前端 js实现 选中数据 动态 添加在表格中

如下图展示&#xff0c;表格上方有属性内容&#xff0c;下拉选中后&#xff0c;根据选中的内容&#xff0c;添加在下方的表格中。 实现方式&#xff0c;&#xff08;要和后端约定&#xff0c;因为这些动态添加的字段都是后端返回的&#xff0c;后端自己会做处理&#xff0c…

UE5.1 透明渲染流程框架图

相关文章&#xff1a; UE 透明物体绘制准备_sh15285118586的博客-CSDN博客 透明直接光和间接光生成_sh15285118586的博客-CSDN博客 Scene:Translucency-Translucency(AfterDOF)_sh15285118586的博客-CSDN博客 Scene:Translucency-Distortion &PostProcessing:ComposeTran…

Jmeter和Postman那个工具更适合做接口测试?

软件测试行业做功能测试和接口测试的人相对比较多。在测试工作中&#xff0c;有高手&#xff0c;自然也会有小白&#xff0c;但有一点我们无法否认&#xff0c;就是每一个高手都是从小白开始的&#xff0c;所以今天我们就来谈谈一大部分人在做的接口测试&#xff0c;小白变高手…

[足式机器人]Part3 变分法Ch01-2 数学预备知识——【读书笔记】

本文仅供学习使用 本文参考&#xff1a; 《变分法基础-第三版》老大中 《变分学讲义》张恭庆 《Calculus of Variations of Optimal Control Theory》-变分法和最优控制论-Daneil Liberzon Ch01-2 数学基础-预备知识1 1.3.2 向量场的通量和散度1.3.3 高斯定理与格林公式 1.3.2 …

Windows下Redis的安装和配置

文章目录 一,Redis介绍二,Redis下载三,Redis安装-解压四,Redis配置五,Redis启动和关闭(通过terminal操作)六,Redis连接七,Redis使用 一,Redis介绍 远程字典服务,一个开源的,键值对形式的在线服务框架,值支持多数据结构,本文介绍windows下Redis的安装,配置相关,官网默认下载的是…

关于Comparable、Comparator接口返回值决定顺序的问题

Comparable和Comparator接口都是实现集合中元素的比较、排序的&#xff0c;下面先简单介绍下他们的用法。 1. 使用示例 public class Person {private String name;private Integer age;public Person() {}public Person(String name, Integer age) {this.name name;this.ag…