「二叉树进阶题解:构建、遍历与结构转化全解析」

在这里插入图片描述

文章目录

  • 根据二叉树创建字符串
    • 思路
    • 代码
  • 二叉树的层序遍历
    • 思路
    • 代码
  • 二叉树的最近公共祖先
    • 思路
    • 代码
  • 二叉搜索树与双向链表
    • 思路
    • 代码
  • 从前序与中序遍历序列构造二叉树
    • 思路
    • 代码
  • 总结

根据二叉树创建字符串

题目:
在这里插入图片描述
样例:
在这里插入图片描述
在这里插入图片描述
可以看见,唯一特殊的就是左子树,当右子树存在的时候左子树不存在的时候,我们需要用()代表空,但是没有左子树,又没有右子树的时候,我们不需要做任何处理。

思路

结合题目和样例,我们可以知道,特殊的是右子树存在但是左子树不存在的情况,这种情况,可以归类为root->left||root->right。这种情况,我们就要处理左子树。首先我们应该处理一下需要返回的字符串,
在这里插入图片描述

  1. 有左子树的情况,当有左子树的时候,我们直接递归左子树,并将结果加上()
  2. 没有左子树,但是有有右子树,也需要递归一次左子树,因为需要加上空的()
  3. 有右子树,直接递归右子树,最后在结果上加上()。

代码

class Solution {
public:string tree2str(TreeNode* root) {if(root==nullptr) return  "";string result=to_string(root->val);if(root->left||root->right){result+="("+tree2str(root->left)+")";}if(root->right){result+="("+tree2str(root->right)+")";}return result;}
};

二叉树的层序遍历

题目:
在这里插入图片描述
样例:
在这里插入图片描述

思路

这道题可以直接借助队列,借助队列的时候我们还需要一个levelsize来记录每层的个数即可

代码

class Solution {
public:vector<vector<int>> levelOrder(TreeNode* root) {if(root==nullptr)return vector<vector<int>>();//创建队列queue<TreeNode*> q;q.push(root);vector<vector<int>> result;int levelsize=1;while(!q.empty()){vector<int> level;for(int i=0;i<levelsize;i++){auto front=q.front();q.pop();if(front->left)q.push(front->left);if(front->right)q.push(front->right);level.push_back(front->val);}result.push_back(level);levelsize=q.size();}return result;}
};

二叉树的最近公共祖先

题目:
在这里插入图片描述
样例:
在这里插入图片描述

思路

需要找公共祖先,首先我们肯定要找到这两个节点的位置,然后这两个节点向上返回,我们用left表示是向左子树搜索这个节点,用right表示向右子树搜索这两个节点,如果能找到就返回对应的节点,p或者q,如果没找到就返回nullptr,如果left和right都不为空说明p和q分布在左子树和右子树,并且root就是两个的最近的祖先,如果其中一个是nullptr说明,p和q分布在一边,直接返回不为空的那个就是最近公共祖先。

代码

class Solution {
public:TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {//找对应的节点if(root==nullptr||root==p||root==q)return root;//记录左子树的结果TreeNode* left=lowestCommonAncestor(root->left,p,q);//记录右子树的结果TreeNode* right=lowestCommonAncestor(root->right,p,q);//如果左右子树都不为空则说明和q分布在左子树和右子树if(left&&right)return root;//如果其中一个是空,则说明p是祖先或者q是祖先return (left==nullptr)?right:left;}
};

二叉搜索树与双向链表

题目:
在这里插入图片描述
样例:
在这里插入图片描述

思路

首先我们来看看子问题:
这肯定是一个中序遍历吧,因为只有中序遍历才能是顺序的,这很明显,接下来就是我们需要处理的中序中间的部分,就是节点之间关系的转变。
在这里插入图片描述

从这里可以知道左指针是指向前驱的指针,右指针是指向后继的指针。
在这里插入图片描述
这里我们分别对左子树和右子树进行中序遍历,第一个遍历到4,因为4是第一个,所以前驱应该是nullptr,因为每次我们都需要前驱,所以这里我们用parent表示前驱,parent就应该被初始化为nullptr,当中序遍历到达4的时候4是不需要处理的因为4的左子树和右子树都是nullptr,唯一需要处理的就是4的前驱应该是nullptr,处理完之后,我们需要返回前驱,因为6需要指向前驱,前驱不为空的情况下还需要将前驱的右指针指向后继,4的后继是6,所以我们只需要进行两个步骤,第一个步骤是处理前驱,前驱是已知节点指向前驱节点,所以我们不用担心是否为空,因为我们的前驱parent初始化是nullptr,所以在parent指向后继的时候,需要判断一下parent是否是空。
最后再改变前驱即可左子树的前驱就是最后一个访问的节点,左中右,所以上图应该是8。

代码

class Solution {
public:TreeNode* parent=nullptr;void InOrder(TreeNode* root){//root是nullptr返回if(!root)return;//中序遍历InOrder(root->left);//先将root的前驱指针指向parent,root赋值给parentroot->left = parent;if(parent) parent->right=root;parent = root;InOrder(root->right);}//左指针指向前面,右指针指向后面TreeNode* Convert(TreeNode* pRootOfTree) {if(pRootOfTree==nullptr)return nullptr;TreeNode* first=pRootOfTree;while(first->left) first=first->left;InOrder(pRootOfTree);return first;}
};

从前序与中序遍历序列构造二叉树

题目:
在这里插入图片描述
样例:
在这里插入图片描述

思路

首先已知两个序列:
在这里插入图片描述
前序和中序,根据前序的特性我们可以知道,第一个元素肯定是根节点,所以这里我们可以根据前序遍历找到根节点,然后在中序遍历中找到根节点的位置。
在这里插入图片描述
找到在中序中的位置之后我们可以通过中序的特性,左边是左子树,右边是右子树,来对左区间和右区间递归,根节点的left指向左区间,根节点的right指向右区间,然后循环这个过程。

代码

class Solution {
public://构建二叉树TreeNode* Build(vector<int>& preorder,int preL,int preR,vector<int> inorder,int inL,int inR){//当左边大于右边的时候返回nullptrif(preL>preR)return nullptr;//找出根节点的值int rootval=preorder[preL];TreeNode *root=new TreeNode(rootval);//找到在中序遍历中的位置int index=inL;while(inorder[index]!=rootval) index++;//计算左子树在前序中的位置int leftSize=index-inL;root->left=Build(preorder,preL+1,preL+leftSize,inorder,inL,index-1);root->right=Build(preorder,preL+leftSize+1,preR,inorder,index+1,inR);return root;}TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {return Build(preorder,0,preorder.size()-1,inorder,0,inorder.size()-1);}
};

总结

通过多道二叉树题目的练习,我们全面了解了二叉树的各种操作和特性。每道题目都涉及不同的场景和技巧,如节点删除、树的遍历、以及特殊结构转换等,不仅加深了对二叉树结构的理解,也提升了编写递归和迭代算法的能力。这些经验为进一步深入数据结构和算法的学习打下了扎实的基础。希望这篇总结能够帮助你在二叉树题目中更得心应手,为更复杂的数据结构问题做好准备。

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

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

相关文章

影刀RPA实战:常见实用功能指令

1. 电脑锁屏与解屏 在实际工作中&#xff0c;我们为了自身工作电脑数据文件的安全&#xff0c;都会为电脑设置密码&#xff0c;当我们离开电脑时&#xff0c;直接锁屏&#xff0c;即使不手动锁屏&#xff0c;也会在一定时间内自动锁屏。 如果你的工作是影刀RPA帮你自动化处理…

Spring Boot驱动的厨艺社交平台设计与实现

5 系统实现 5.1食材分类管理 管理员管理食材分类&#xff0c;可以添加&#xff0c;修改&#xff0c;删除食材分类信息。下图就是食材分类管理页面。 图5.1 食材分类管理页面 5.2 用户信息管理 管理员管理用户信息&#xff0c;可以添加&#xff0c;修改&#xff0c;删除用户信…

kafka 分布式(不是单机)的情况下,如何保证消息的顺序消费?

大家好&#xff0c;我是锋哥。今天分享关于【kafka 分布式&#xff08;不是单机&#xff09;的情况下&#xff0c;如何保证消息的顺序消费?】面试题&#xff1f;希望对大家有帮助&#xff1b; kafka 分布式&#xff08;不是单机&#xff09;的情况下&#xff0c;如何保证消息的…

量子变分算法 (python qiskit)

背景 变分量子算法是用于观察嘈杂的近期设备上的量子计算效用的有前途的候选混合算法。变分算法的特点是使用经典优化算法迭代更新参数化试验解决方案或“拟设”。这些方法中最重要的是变分量子特征求解器 (VQE)&#xff0c;它旨在求解给定汉密尔顿量的基态&#xff0c;该汉密尔…

mac 上使用 cmake 构建包含 OpenMP 的项目

安装依赖 # clang 默认不支持 -fopenmp&#xff0c;因为它没有内置 OpenMP 支持。 # 为了解决这个问题&#xff0c;需要安装 libomp 并配置 clang 使用 libomp brew install libomp# macOS 自带的 clang 编译器被修改过&#xff0c;默认禁用了 OpenMP&#xff0c; # 而不支持 …

【K8S系列】Kubernetes Service 基础知识 详细介绍

在 Kubernetes 中&#xff0c;Service 是一种抽象的资源&#xff0c;用于定义一组 Pod 的访问策略。它为这些 Pod 提供了一个稳定的访问入口&#xff0c;解决了 Pod 可能频繁变化的问题。本文将详细介绍 Kubernetes Service 的类型、功能、使用场景、DNS 和负载均衡等方面。 1.…

class 36 二叉树高频题目 - 上 (不含有树形dp)

1. BFS 的两种方式 如下图, 是一个二叉树. 我们需要按照层的方式来遍历这棵树. 1.1 使用 JDK 自带的类实现(链表实现, 经典 BFS) 首先我们实现一个队列, 这个队列从头进, 从尾出.然后将根节点放入其中, 然后将放入的节点弹出,然后继续验证弹出的节点有没有左孩子, 若是有, 将…

【HTML】之form表单元素详解

HTML表单是网页与用户交互的关键组成部分&#xff0c;它允许用户输入数据并将数据提交到服务器进行处理。本文将全面详细地介绍HTML表单的各个方面&#xff0c;从基础元素到高级用法&#xff0c;并提供丰富的代码示例和中文注释&#xff0c;帮助你彻底掌握表单的使用。 1. 表单…

强大!Spring Boot 3.3 集成 PDFBox 轻松实现电子签章功能!

强大&#xff01;Spring Boot 3.3 集成 PDFBox 轻松实现电子签章功能&#xff01; 随着数字化办公和电子合同的普及&#xff0c;PDF 文档已经成为很多业务场景中的标准文件格式。为了确保文档的安全性和法律效力&#xff0c;电子签章技术应运而生。电子签章不仅可以证明文件的…

视频美颜平台的搭建指南:基于直播美颜SDK的完整解决方案

众所周知&#xff0c;直播美颜SDK是实现视频美颜功能的核心。本文将详细解析如何基于直播美颜SDK搭建一个完整的视频美颜平台。 一、视频美颜SDK的核心功能 直播美颜SDK作为平台的技术核心&#xff0c;能够提供丰富的美颜效果和稳定的视频处理能力。通常&#xff0c;SDK具备以…

传输层TCP

报头 1.报头和有效载荷如何分离将&#xff0c;有效载荷向上交付&#xff1f; tcp有个标准报头长度为20&#xff0c;那是不是以为我们可以像udp一样分离依靠报头大小去分离&#xff0c;我们仔细去看我们报头中还有个选项没包含到。 我们还有个首部长度&#xff0c;四位可以表…

【Axure高保真原型】分级树筛选中继器表格

今天和大家分享分级树筛选中继器表格的原型模板&#xff0c;点击树的箭头可以展开或者收起子级内容&#xff0c;点击内容&#xff0c;可以筛选出该内容及子级内容下所有的表格数据。左侧的树和右侧的表格都是用中继器制作的&#xff0c;所以使用也很方便&#xff0c;只需要在中…

SwiftUI:单个App支持设置多语言

SwiftUI 全新多语言方案 简化本地化的字符串- WWDC21 - 视频 本地化您的SwiftUI app - WWDC21 - 视频 构建全球化App&#xff1a;本地化的示例- WWDC22 - 视频 构建支持多语言的App - WWDC24 - 视频 单个App支持设置多语言 工程 Info.plist里添加 键值UIPrefersShowingLangua…

论1+2+3+4+... = -1/12 的不同算法

我们熟知自然数全加和&#xff0c; 推导过程如下&#xff0c; 这个解法并不难&#xff0c;非常容易看懂&#xff0c;但是并不容易真正理解。正负交错和无穷项计算&#xff0c;只需要保持方程的形态&#xff0c;就可以“预知”结果。但是这到底说的是什么意思&#xff1f;比如和…

【AI换装整合及教程】CatVTON:时尚与科技的完美融合

在当今数字化时代&#xff0c;时尚行业正经历着一场前所未有的变革&#xff0c;而 CatVTON 作为一款由中山大学、Pixocial 等机构联合研发的轻量化 AI 虚拟换装工具&#xff0c;无疑是这场变革中的璀璨明星。 一、独特的技术架构 CatVTON 基于 Stable Diffusion v1.5 inpainit…

css 切角实现(全)

效果 样式代码 <template><div class"container"><div class"clip-all-angle"> 4个角全部剪切 </div><div class"clip-two-angle"> 切底部两个角 </div><div class"clip-two-top-angle"> …

新鲜出炉,ECCV2024.9.25 首次提出基于 YOLO 目标检测的无源域自适应

原文标题&#xff1a;Source-Free Domain Adaptation for YOLO Object Detection 中文标题&#xff1a;基于 YOLO 目标检测的无源域自适应 论文地址&#xff1a; https://arxiv.org/abs/2409.16538 代码地址&#xff1a; GitHub - vs-cv/sf-yolo 1、Abstract 无源域自适应&…

ACL访问控制

要求&#xff1a; PC1与PC2不能通信。PC1可以和PC3通信。PC2可以和PC3通信。 1. VLAN配置 根据拓扑图的连接&#xff0c;PC1、PC2、PC3属于不同的VLAN。我们需要确保交换机上的端口已经正确划分到不同的VLAN。假设交换机接口的VLAN配置已经完成&#xff08;其他博文有)&…

【Linux】线程池详解及其基本架构与单例模式实现

目录 1.关于线程池的基本理论 1.1.线程池是什么&#xff1f; 1.2.线程池的应用场景&#xff1a; 2.线程池的基本架构 2.1.线程容器 2.2.任务队列 2.3.线程函数&#xff08;HandlerTask&#xff09; 2.4.线程唤醒机制 3.添加单例模式 3.1.单例模式是什么&…

多IP访问网站

1.创建挂载点 mount /dev/sr0 /mnt vim /etc/yum.repos.d/base.repo [BaseOS] nameBaseOS baseurlfile:///mnt/BaseOS gpgcheck0 [Appstream] nameAppStream baseurlfile:///mnt/AppStream gpgcheck0 2.关闭防火墙等 systemctl stop firewalld setenforce 0 3.下载nginx…