二叉搜索树在线OJ题讲解

二叉树创建字符串

在这里插入图片描述
在这里插入图片描述

我们首先进行题目的解读:
大概意思就是用()把每个节点的值给括起来,然后再经过一系列的省略的来得到最后的结果

大家仔细观察题目给出的列子就可以发现,其实这个题目可以大致分为三种情况:

1 节点的左孩子和右孩子都在,不能省略括号
2 节点没有左孩子只有右孩子,不能省略括号
3 节点没有右孩子只有左孩子,可以省略这个空节点的括号,用来区分第二种情况,保证了一个字符串只能对应一个二叉搜索树

就比如例1:
在这里插入图片描述

例子中给出的初步转化的字符串是没有经过省略的,其实4后面还要加上两个空括号才完美,这里题目有一点小误差

就比如节点2他的右孩子节点是空的,所以那个括号就要省略,4和3的两个括号都省略,就可以得到最后的结果了

代码如下:
我们首先定义一个字符串,如果根节点root为空,就直接返回这个空字符串,不为空先+=root内存储的val
如果root的左孩子节点或者root的右孩子节点不为空的话,就要把root的左孩子节点的val用括号括起来,就算左孩子为空这个括号也不能省略
如果root的右孩子不为空就要把root的右孩子用括号括起来,最后 返回时str即可

class Solution {
public:
    string tree2str(TreeNode* root) 
    {
        string str;
        if(root==nullptr)
            return str;
        str+=to_string(root->val);
        if(root->left||root->right)
       { 
        str+='(';
        str+=tree2str(root->left);
        str+=')';
        }
        if(root->right)
        {
         str+='(';
         str+=tree2str(root->right);
         str+=')';
        }
        return str;
    }
};
二叉树的分层遍历


在这里插入图片描述
这个题目是一个典型的vector里面套vector(int)的题目,他最后返回的是双层结构
在这里插入图片描述
我们可以用到一个队列,这个队列用来存放节点,而双层的vector容器就用来存放层序遍历节点的val,最后返回

我们先将root节点放进队列,然后当他出来后,将他的左右孩子节点放入队列,只要队列不为空不就继续
在这里插入图片描述
完整代码如下:

class Solution {
public:
    vector<vector<int>> levelOrder(TreeNode* root) 
    {
        queue<TreeNode*> q;
        vector<vector<int>> vv;
        if(root==nullptr)
            return vv;
        int levelsize=0;
        q.push(root);
        levelsize=q.size();
        while(!q.empty())
        {
            vector<int> v;
            while(levelsize--)
        {
            TreeNode* node=q.front();
            q.pop();
            v.push_back(node->val);
            if(node->left)
                q.push(node->left);
            if(node->right)
                q.push(node->right);
        }
        vv.push_back(v);
        levelsize=q.size();
        }
        return vv;
    }
};


在这里插入图片描述
自底向上的层序遍历,我们就偷懒直接用上面的代码,用一个reverse函数反转即可:

将vv的迭代器反转

class Solution {
public:
    vector<vector<int>> levelOrderBottom(TreeNode* root) {
        queue<TreeNode*> q;
        vector<vector<int>> vv;
        if(root==nullptr)
            return vv;
        int levelsize=0;
        q.push(root);
        levelsize=q.size();
        while(!q.empty())
        {
            vector<int> v;
            while(levelsize--)
        {
            TreeNode* node=q.front();
            q.pop();
            v.push_back(node->val);
            if(node->left)
                q.push(node->left);
            if(node->right)
                q.push(node->right);
        }
        vv.push_back(v);
        levelsize=q.size();
        }
        reverse(vv.begin(),vv.end());
        return vv;
    }
};
最近公共祖先

在这里插入图片描述
在这里插入图片描述
其实我们画图之后可以看到,公共祖先节点有几个很明显的特征:
如果一个节点在本节点的左子树,另一个在本节点的右子树上,那么这个节点就是那两个节点的公共祖先

如果两个节点都在一个节点的左或者右我们就用一个辅助函数来递归完成,都在左边或者右边那么两个节点之中有一个一定时他们两个节点的公共祖先
在这里插入图片描述
完整代码如下:

class Solution {
public:
//判断是否在这个树上
bool isintree(TreeNode* root,TreeNode* x)
{
    if(root==nullptr)
        return false;
    if(root==x)
        return true;
    return isintree(root->left,x)||isintree(root->right,x);
}
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) 
    {
        if(root==p||root==q)
            return root;
        bool pinleft=isintree(root->left,p);
        bool pinright=isintree(root->right,p);
        bool qinleft=isintree(root->left,q);
        bool qinright=isintree(root->right,q);
        //一个在左一个在右
        if((pinleft&&qinright)||(pinright&&qinleft))
            return root;
        //都在左
        if(pinleft&&qinleft)
            return lowestCommonAncestor(root->left,p,q);
        //都在右
        if(pinright&&qinright)
            return lowestCommonAncestor(root->right,p,q);
        return nullptr;
    }
};
二叉树搜索树转换成排序双向链表

在这里插入图片描述
我们观察可以看到,最后排序出来的双向链表是一个有序的链表,而二叉搜索树的中序遍历一定是一个有序的序列,所以我们在这里要定义一个中序遍历的函数来用到解题

我们需要用到一个辅助的prev节点,令cur的left为prev,如果prev不为空就令prev的right为cur即可
在这里插入图片描述

class Solution {
public:
	void inorder(TreeNode* cur,TreeNode*& prev)
	{
		if(cur==nullptr)
			return;
		inorder(cur->left,prev);
		cur->left=prev;
		if(prev)
			prev->right=cur;
		prev=cur;
		inorder(cur->right,prev);
	}
    TreeNode* Convert(TreeNode* pRootOfTree) 
	{
		TreeNode* prev=nullptr;
		inorder(pRootOfTree,prev);
		TreeNode* head=pRootOfTree;
		while(head&&head->left)
		{
			head=head->left;
		}
		return head;
    }
};
前序中序还原二叉树

在这里插入图片描述
本题是根据前序和中序来构造二叉树,我们知道前序的第一个节点就是二叉树的根节点,而中序中根节点左边的就是左子树,右边为右子树,然后再遍历前序第二个节点,再次带入中序,前序的“根节点”能够将中序分为两个区间,分为区间后我们再递归两个区间
在这里插入图片描述

完整代码如下:

class Solution {
public:
    TreeNode* _buildTree(vector<int>& preorder,vector<int>& inorder,int& prei,int begin,int end)
    {
        if(begin>end)
            return nullptr;
        TreeNode* root=new TreeNode(preorder[prei]);
        int rooti=begin;
        while(rooti<=end)
        {
            if(inorder[rooti]==preorder[prei])
                break;
            else
                rooti++;
        }
        prei++;
        root->left=_buildTree(preorder,inorder,prei,begin,rooti-1);
        root->right=_buildTree(preorder,inorder,prei,rooti+1,end);
        return root;
    }
    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) 
    {
        int i=0;
        return _buildTree(preorder,inorder,i,0,inorder.size()-1);
    }
};
中序和后序还原二叉树

在这里插入图片描述
中序和后续构造二叉树就和前序和后续构造一样,转变一个思路:
但是要注意,由于后序是左右根,所以要先递归右在递归左

class Solution {
public:
    TreeNode* _buildTree(vector<int>& inorder, vector<int>& postorder,int& prei,int begin,int end)
    {
        if(begin>end)
            return nullptr;
        TreeNode* root=new TreeNode(postorder[prei]);
        int rooti=begin;
        while(rooti<=end)
        {
            if(inorder[rooti]==postorder[prei])
                break;
            else
                rooti++;
        }
        prei--;
        
        root->right=_buildTree(inorder,postorder,prei,rooti+1,end);
        root->left=_buildTree(inorder,postorder,prei,begin,rooti-1);
        
        return root;
    }
    TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) 
    {
        int i= postorder.size()-1;
        return _buildTree(inorder,postorder,i,0,inorder.size()-1);
    }
};

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

git安装与使用4.3

一、git的安装 1、下载git包 下载git包url&#xff1a;https://git-scm.com/download/win 下载包分为&#xff1a;64位和32位 2、点击安装包 2、选择安装路径 3、 点击下一步 4、点击next 5、点击next 6、点击next 7、 8、 9、 10、 11、 12、在桌面空白处&#xff0c;右键…

服务器上部署WEb服务方法

部署Web服务在服务器上是一个比较复杂的过程。这不仅仅涉及到配置环境、选择软件和设置端口&#xff0c;更有众多其它因素需要考虑。以下是在服务器上部署WEb服务的步骤&#xff1a; 1. 选择服务器&#xff1a;根据项目规模和预期访问量&#xff0c;选择合适的服务器类型和配置…

2024.02.29作业

1. TCP模型 server #include "test.h"#define SER_IP "192.168.191.128" #define SER_PORT 9999int main(int argc, char const *argv[]) {int sfd -1;sfd socket(AF_INET, SOCK_STREAM, 0);if (-1 sfd){perror("socket error");return -1;…

Tomcat部署Web服务器及基础功能配置

前言 Tomcat作为一款网站服务器&#xff0c;目前市面上Java程序使用的比较多&#xff0c;作为运维工人&#xff0c;有必要了解一款如何去运行Java环境的网站服务。 目录 一、Java相关介绍 1. Java历史 2. Java跨平台服务 3. Java实现动态网页功能 3.1 servelt 3.2 jsp …

【排序算法】基数排序

一&#xff1a;基本概念 1.1 基数排序(桶排序)介绍 基数排序&#xff08;radix sort&#xff09;属于“分配式排序”&#xff08;distribution sort&#xff09;&#xff0c;又称“桶子法”&#xff08;bucket sort&#xff09;或bin sort&#xff0c;顾名思义&#xff0c;它是…

2024最新ChatGPT网站源码AI绘画系统:SparkAI系统(Ai智能问答系统和Midjourney绘画系统)

一、前言 SparkAi创作系统是基于ChatGPT进行开发的Ai智能问答系统和Midjourney绘画系统&#xff0c;支持OpenAI-GPT全模型国内AI全模型。本期针对源码系统整体测试下来非常完美&#xff0c;那么如何搭建部署AI创作ChatGPT&#xff1f;小编这里写一个详细图文教程吧。已支持GPT…

2.模拟问题——2.使用二维数组输出图形

用二维数组描述图形 首先要计算出整个输出的方框大小&#xff0c;从而判定相应关键循环点 #include <cstdio> char arr[1000][3000]; int main() {int h;//初始化&#xff0c;全部内部填空格while(scanf("%d",&h) ! EOF){for (int i 0; i < h; i) {f…

【JavaEE】_Spring MVC项目之建立连接

目录 1. Spring MVC程序编写流程 2. 建立连接 2.1 RequestMapping注解介绍 2.2 RequestMapping注解使用 2.2.1 仅修饰方法 2.2.2 修饰类与方法 2.3 关于POST请求与GET请求 2.3.1 GET请求 2.3.2 POST请求 2.3.3 限制请求方法 1. Spring MVC程序编写流程 1. 建立连接&…

vmware虚拟机centos中/dev/cl_server8/root 空间不够

在使用vmware时发现自己的虚拟机的/dev/cl_server8/root空间不够了&#xff0c;没办法安装新的服务。所以查了一下改空间的办法。 1.在虚拟机关闭的状态下&#xff0c;选中需要扩容的虚拟机->设置->硬件-> 硬盘->扩展->填写扩大到的值。 2.打开虚拟机&#xff…

力扣SQL50 寻找用户推荐人 查询

Problem: 584. 寻找用户推荐人 思路 null不可以直接与数值类比较 Code select name from Customer where ifnull(referee_id,0) ! 2;

Day08-【Java SE进阶】面向对象高级二——多态、final、抽象类、接口

一、多态 对象多态多态是在继承/实现情况下的一种现象&#xff0c;表现为对象多态和行为多态。 对象多态&#xff1a;一个人可以是学生也可以是老师&#xff0c;学生和老师都是人的子类&#xff0c;创建人对象让其指向不同的对象&#xff0c;称为对象多态&#xff0c;这里是向…

【办公类-25-01】20240304 UIBOT上传 ”班级主页-主题知识“

作品展示&#xff1a; 一、背景需求&#xff1a; 本学期制作了 “信息窗主题说明”合并A4内容 【办公类-22-07】周计划系列&#xff08;3-1&#xff09;“信息窗主题知识&#xff08;提取&#xff09;” &#xff08;2024年调整版本&#xff09;-CSDN博客文章浏览阅读797次&a…

深度学习 精选笔记(9)分布偏移

学习参考&#xff1a; 动手学深度学习2.0Deep-Learning-with-TensorFlow-bookpytorchlightning ①如有冒犯、请联系侵删。 ②已写完的笔记文章会不定时一直修订修改(删、改、增)&#xff0c;以达到集多方教程的精华于一文的目的。 ③非常推荐上面&#xff08;学习参考&#x…

在学习云原生的时候,一直会报错ImagePullBackOff Back-off pulling image

在学习云原生的时候&#xff0c;一直会报错 &#xff08;见最后几张图&#xff09; ImagePullBackOff Back-off pulling image 然后我就在像。这个配置的镜像是不是可以自己直接下载&#xff0c;但是好像不怎么搜索得到 然后就在想&#xff0c;这个lfy_k8s_images到底是个啥玩…

c++面试一

1.#include使用 在C/C中&#xff0c;#include 预处理指令用于包含头文件&#xff0c;这些头文件通常包含了函数声明、宏定义以及其他的声明和定义。#include 指令后面跟着的文件名可以使用双引号 "" 或尖括号 <> 来指定&#xff0c;它们之间有一些区别。 双引…

MyBatis概述

三层架构 表现层&#xff1a;直接和前端交互&#xff0c;接受AJAX请求&#xff0c;返回json数据业务层&#xff1a;一是处理前端的请求&#xff0c;二是返回持久层获取的数据持久层(数据访问层)&#xff1a;直接操作数据库&#xff0c;完成CRUD&#xff0c;返回数据给业务层 …

Tomcat服务部署、优化

一 Tomcat的基本介绍 Tomcat概念 Tomcat 服务器是一个免费的开放源代码的Web 应用服务器&#xff0c;属于轻量级应用服务器&#xff0c;在中小型系统和并发访问用户不是很多的场合下被普遍使用&#xff0c;是开发和调试 JSP 程序的首选。 当在一台机器上配置好Apache 服务器…

宋Pro 荣耀版10.98万元起,开启“清场”模式!

2024年3月1日&#xff0c;比亚迪荣耀全家桶再添大将&#xff0c;万众期待的宋Pro DM-i荣耀版以10.98万元起的价格震撼推出。新车共推出5款车型&#xff0c;官方指导价10.98万元——13.98万元&#xff0c;重新锚定A级SUV市场新价值&#xff0c;在该细分市场正式拉开“电比油低”…

鼠标失灵怎么办?电脑出现鼠标失灵的详细处理方法介绍

无论是笔记本电脑还是台式机电脑&#xff0c;鼠标是必不可少的外设之一&#xff0c;而我们在使用电脑的过程中&#xff0c;经常回遇到鼠标突然失灵了&#xff0c;不听使唤&#xff0c;控制不了&#xff0c;接下小编来与大家一起分享&#xff0c;遇到这种情况我们该怎么办 有时…

iconv 更改字符串编码操作

概要 在日常开发中&#xff0c;中文字符乱码是一个经常遇到的问题。在解决此问题时&#xff0c;遇到一个比较好用的字符串编码开源库&#xff0c;在此进行总结。 整体思路流程 iconv官网地址&#xff1a;http://www.gnu.org/software/libiconv/ 这里主要使用的相关接口&…
最新文章