二叉树,二叉搜索树相关模板

news2024/11/16 18:42:38

目录

  • 1.先序遍历
  • 2.中序遍历
  • 3.后序遍历
  • 4.层序遍历(可用于需按层进行计算的题目)
  • 5.判定二叉树的对称性
  • 6.二叉树最大深度(结点深度:根节点到该结点。结点高度:该结点到叶子结点)
  • 7.二叉树最小深度
  • 8.二叉树的平衡性
  • 9.求左叶子的和
  • 10.通过中序和后序序列构造二叉树
  • 11.二叉搜索树相关问题
    • 11.1.验证二叉搜索树的性质(这题我用了前序遍历)
    • 11.2.二叉搜索树的最小绝对差
  • 12.公共祖先问题

1.先序遍历

void PreOrder(TreeNode* root){
    if(root==NULL)
        return;
        
    //要对头结点进行的操作
    
    if(root->left!=NULL)
        PreOrder(root->left);
    if(root->right!=NULL)
        PreOrder(root->right);
}

2.中序遍历

void InOrder(TreeNode* root){
    if(root==NULL)
        return;
    if(root->left!=NULL)
        InOrder(root->left);
        
    //要对头结点进行的操作
    if(root->right!=NULL)
    
        InOrder(root->right);
}

3.后序遍历

void PostOrder(TreeNode* root){
    if(root==NULL)
        return;
    if(root->left!=NULL)
        PostOrder(root->left);
    if(root->right!=NULL)
        PostOrder(root->right);
        
    //要对头结点进行的操作
    
}

4.层序遍历(可用于需按层进行计算的题目)

//直接给出函数体
if(root==NULL)
    return;
queue<TreeNode*> q;//创建队列,也可以用大点的数组然后双指针
TreeNode* temp;
q.push(root);//头结点入队
int size;//用来保存当轮结点数量

while(!q.empty()){
    size=q.size();//统计当层结点数量
    for(int i=0;i<size;i++){//把单层结点出队完,for循环才结束
        temp=q.front();
        q.pop();//队头结点出队
        if(temp->left!=NULL)
            q.push(temp->left);//左孩子入队
        if(temp->right!=NULL)
            q.push(temp->right);//右孩子入队
    }
}

5.判定二叉树的对称性

bool isSymmetric(TreeNode* left,TreeNode* right){
    if(left==NULL&&right==NULL)//两个结点同时为空则对称
        return true;
    if(left==NULL||right==NULL)
    //同时为空的情况被上面筛去了,这里判断的是只有一方为空,则不对称
        return false;
    if(left->val!=right->val)
    //值不一样,不对称
        return false;
    bool t1=isSymmetric(left->left,right->right);
    //递归判断左子树的左孩子和右子树的右孩子
    bool t2=isSymmetric(left->right,right->left);
    //递归判断左子树的右孩子和右子树的左孩子
    return t1&&t2;//同时为真才对称
}

6.二叉树最大深度(结点深度:根节点到该结点。结点高度:该结点到叶子结点)

int getMaxDepth(TreeNode* root){
    if(root==NULL)
        return 0;
    int left=getMaxDepth(root->left);
    int right=getMaxDepth(root->right);
    int depth=(left>right?left:right)+1;
    return depth;
}

7.二叉树最小深度

int  getMinDepth(TreeNode* root){
    if(root==NULL)
        return 0;//结点为空,深度为0
    if(root->left==NULL&&root->right==NULL)
        return 1;//叶子结点深度为1
    int left=INT_MAX://左子树深度,初始化为最大值
    int right=INT_MAX;//右子树深度。初始化为最大值
    if(root->left!=NULL)
        left=getMinDepth(root->left);
    if(root->right!=NULL)
        right=getMinDepth(root->right);
        //只有子树非空,才返回小的深度,否则数值都是最大值MAX_INT
        //控制住每层深度缩小的途径
    return left>right?right:left;
    //将左、右子树中较小的深度值返回
}

8.二叉树的平衡性

int isBalance(TreeNode* root){//这个函数设定返回-1说明不平衡
    if(root==NUL)
        return 0;
    int left=0;
    int right=0;
    int res;
    if(root->left!=NULL)//左子树非空,递归左子树
        left=isBalance(root->left);
    if(root->right!=NULL)//右子树非空,递归右子树
        right=isBalance(root->right);
    if(left==-1||right==-1)//左右子树有一个不平衡,则整棵树不是平衡树
        res=1-;
    else{//左右子树平衡,则判断当层
        if(abs(left-right)>1)//左右子树高度差大于一,则不平衡
            res=-1;
        else//否则,返回左右子树中最大的深度,再加上当层的深度1
            res=(left>right?left:right)+1;
    }
    return res;
}

9.求左叶子的和

int sumOfLeftLeaves(TreeNode *root){
    if(root==NULL)
        return 0;
    int left;
    if(root->left!=NULL&&root->left->left==NULL&&root->left->right==NULL)
        left=root->left->val;
    else
        left=sumOfLeftLeaves(root->left);
    int right=sumOfLeftLeaves(root->right);
    return left+right;
}

10.通过中序和后序序列构造二叉树

TreeNode* BuildTree(vector<int>& inorder, vector<int>& postorder,int ll,int lr,int pl,int pr){
//ll、lr是中序序列的下标范围,pl、pr是后序序列的下标范围
    if(pl>pr)
        return NULL;
    TreeNode* root=new TreeNode(postorder[pr]);
    int index;
    for(index=0;index<inorder.size();index++){
        if(inorder[index]==root->val)
            break;
    }
    root->left=BuildTree(inorder,postorder,ll,index-1,pl,pl+index-1-ll);
    root->right=BuildTree(inorder,postorder,index+1,lr,pl+index-ll,pr-1);
    return root;
}

其实可以抽象出一个用数组构造二叉树的模板

if(左下标>右下标)//先标出结束递归的条件,即出口
    return NULL;
TreeNode* root=new TreeNode(结点的值);//构造本结点
root->left=(递归调用函数);//构造本结点的左子树
root->right=(递归调用函数);//构造本结点的右子树

11.二叉搜索树相关问题

由于二叉搜索树全树具有  左子树<当前结点<右子树  的特点,所以很多都要用到中序遍历(在中序遍历中,全树结点的遍历顺序为左子树结点->当前结点->右子树结点,因此遍历出来得到的序列为升序序列),利用二叉搜索树的特性进行遍历。
另外,如果遇到要保留二叉搜索树某个范围的结点的话(修剪二叉搜索树),如果根节点满足条件,而左子树某结点不满足保留条件,要删除的话,需要判断该结点的右子树是否满足条件。
因为如果左子树某结点不满足保留的范围的话,由于二叉搜索树具有的  左子树<当前结点<右子树  性质,因此该结点一定是小于保留的范围的,而该结点的右子树大于该结点,所以不能直接删除,需要继续判断右子树是否满足保留条件。
根节点的右子树同理。

11.1.验证二叉搜索树的性质(这题我用了前序遍历)

long long min_num=LONG_MIN;
long long max_num=LONG_MAX;
bool isValid(TreeNode *root,long long min_num,long long max_num){
    if(root==NULL)
        return true;
    if(root->val<=min_num)
        return false;
    if(root->val>=max_num)
        return false;
        
    bool left=isValid(root->left,min_num,root->val);
    //因为左子树<当前结点,所以当前结点比左子树任何结点都大
    //因此把当前结点的值作为最大值传入
    bool right=isValid(root->right,root->val,max_num);
    //因为当前结点<右子树,所以当前结点比右子树任何结点都小
    //因此把当前结点的值作为最小值传入
}

11.2.二叉搜索树的最小绝对差

题意
这题需要计算每两个结点之间的差值,并返回其中的最小值。由于在中序遍历中序列的值呈升序,而在该升序中序列,每个数的大小肯定是跟与之相邻的数的大小最接近,因此可以采用中序遍历的方式,从前向后两两计算前后两个结点的差值,取出其中的最小值。
但是在之前的中序遍历中,我们只能看到当前结点的值,最多是当前结点的左右子树的值,如果遇到以下这种情况,如何判断1号结点和3号结点的值呢?
蓝色线是中序遍历的顺序
我们可以用一个结点专门保存上一个结点的指针,当轮计算完成后再用该结点保存当前结点的指针,遍历下一个结点,以下是代码,也可以作为需要比较树的前后关系的模板。

    void getMin(TreeNode* root,TreeNode*& pre,int& min){
    if(root==NULL)
        return;
    if(root->left!=NULL)
        getMin(root->left,pre,min);
    //以上是中序遍历模板
    if(pre!=NULL){
        int temp=abs(pre->val-root->val);
        if(temp<min)
            min=temp;
    }
    //以下两行是中序遍历模板
    if(root->right!=NULL)
        getMin(root->right,root,min);
    pre=root;
    //修改pre再返回,比如当前正在访问上面图片的1号结点,执行到这里后
    //会将1号结点保存后再返回,然后会一路返回到2号的父节点3号
    //进行if(pre!=NULL)那一行的计算,对比pre(即1号结点)和3号结点的值
    //这就是 pre=root 的用意
}

12.公共祖先问题

因为后序遍历的顺序为 左子树->右子树->当前结点 ,即从下往上找,因此可以采用后序遍历寻找树的公共祖先
    TreeNode* CommonAncestor(TreeNode* root,TreeNode* p,TreeNode* q){
        if(root==NULL)
            return NULL;
        //用来保存左右子树的寻找结果,初始化为NULL
        //一定要提前声明,因为if不一定满足条件,没提前声明又不满足的话,最后会报错
        TreeNode* left=NULL;
        TreeNODe* right=NULL;
        //后序遍历
        if(root->left!=NULL)
            left=CommonAncestor(root->left,p,q);
        if(root->right!=NULL)
            right=CommonAncestor(root->right,p,q);
        //如果当前结点是想寻找的其中一个结点,就返回此结点
        if(root==p||root==q)
            return root;
        //如果左右子树都非空,说明这个root的左右子树中分别有p或q,说明root是最近的公共祖先
        if(left&&right)
            return root;
        //如果左子树或右子树存在非空值,返回此值,否则返回的是NULL
        return (left?left:right);
    }

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

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

相关文章

ArcGIS制图技巧:制图入门与点、线、面状符号制作

目的&#xff1a; 1、了解地图制作目的&#xff1b; 2、了解在ArcMap平台中制作地图大致过程。 3、掌握地形图生成的操作&#xff1b; 4、掌握地形图的正确输出方法。 5、理解点状符号、线状符号、面状符号的基本概念&#xff1b; 6、理解地形点状符号、线状符号、面状符…

从大专到测开,上海某字母站大厂的面试题,岗位是测开(25K*16)

简单介绍一句&#xff0c;大专出身&#xff0c;三年经验。跳了四次槽&#xff0c;面试了无数次&#xff0c;现在把自己的面试经验整理出来分享给大家&#xff0c;堪称必杀技&#xff01; 1&#xff0c;一切从实际出发&#xff0c;对实际工作进行适当修饰 2&#xff0c;不会的简…

【晓龙oba出品 - 黑科技解题系列】- 最小操作次数使数组元素相等

思路 算法归根到底就是找规律的游戏&#xff0c;我们首先来看一个现象&#xff1a; 以数组nums [1,2,3,4,5]为例 当我们将数组排序后&#xff0c;可以知道最小值为1,最大值为5&#xff0c;此时我们需要四次运算可以使最小值与最大值相等&#xff1a; 第一次&#xff1a;2,3,4,…

HNU-电子测试平台与工具2-数模转换

数模转换实验 计科XXXX wolf 工程文件我也一并上传了 D级任务 一.实验任务 对74194进行仿真验证&#xff0c;掌握Quartus仿真的基本原则和常规步骤&#xff0c;记录移位寄存器的数据读写&#xff0c;并描述仿真波形&#xff0c;分析结果。 二.实验过程 1.电路连接 2.功能…

Go 实现多态和 参数的动态个数及动态类型

引子 go语言作为静态(编译期类型检测)强类型(手写代码进行类型转换)语言, 要想实现 动态语言的鸭子类型的调用方法,做到 一个入参是不同类型,还是有些麻烦的; 需求 希望写代码时像python一样的鸭子类型,不用管参数类型,都可以调用同一个方法;希望 入参像python一样 能够在 个…

Kalman Filter in SLAM (1) ——Data Fusion and Kalman Filter(数据融合和卡尔曼滤波)

文章目录0. 参考资料1. Intro Example 例子引入1.1. 测量硬币直径1.2. 思考2. Data Fusion 数据融合2.1. 数据融合在做什么&#xff1f;2.2. 数据融合的前提——不确定度2.3. 数据融合的结果——统计意义下的最优估计3. State Space Representation 状态空间表达式3.1. 状态方程…

大数据 | (二)SSH连接报错Permission denied

大数据 | &#xff08;三&#xff09;centos7图形界面无法执行yum命令&#xff1a;centos7图形界面无法执行yum命令 哈喽&#xff01;各位CSDN的朋友们大家好&#xff01; 今天在执行Hadoop伪分布式安装时&#xff0c;遇到了一个问题&#xff0c;在此跟大家分享&#xff0c; …

ThreadLocal的内部结构和源码探究

目录一. ThreadLocal的内部结构1 常见的误解2 现在的设计3 这样设计的好处二. ThreadLocal的核心方法源码1 set方法2 get方法3 remove方法**4 initialValue方法**三. ThreadLocalMap源码分析1 基本结构2 弱引用和内存泄漏3 hash冲突的解决一. ThreadLocal的内部结构 ​ 通过之…

【C++知识点】STL 容器总结

✍个人博客&#xff1a;https://blog.csdn.net/Newin2020?spm1011.2415.3001.5343 &#x1f4da;专栏地址&#xff1a;C/C知识点 &#x1f4e3;专栏定位&#xff1a;整理一下 C 相关的知识点&#xff0c;供大家学习参考~ ❤️如果有收获的话&#xff0c;欢迎点赞&#x1f44d;…

2月榜单丨飞瓜数据B站UP主排行榜(哔哩哔哩平台)发布!

飞瓜轻数发布2023年2月飞瓜数据UP主排行榜&#xff08;B站平台&#xff09;&#xff0c;通过充电数、涨粉数、成长指数三个维度来体现UP主账号成长的情况&#xff0c;为用户提供B站号综合价值的数据参考&#xff0c;根据UP主成长情况用户能够快速找到运营能力强的B站UP主。飞瓜…

(蓝桥真题)剪格子(搜索+剪枝)

样例1输入&#xff1a; 3 3 10 1 52 20 30 1 1 2 3 样例1输出&#xff1a; 3 样例2输入&#xff1a; 4 3 1 1 1 1 1 30 80 2 1 1 1 100 样例2输出&#xff1a; 10 分析&#xff1a;这道题目我们直接从(1,1)点开始进行dfs搜索即可&#xff0c;但是需要注意一点的是我们搜…

FPGA和IC设计怎么选?哪个发展更好?

很多人纠结FPGA和IC设计怎么选&#xff0c;其实往小了说&#xff0c;要看你选择的具体是哪个方向岗位。往大了说&#xff0c;将来你要是走更远&#xff0c;要成为大佬&#xff0c;那基本各个方向的都要有涉及的。 不同方向就有不同的发展&#xff0c;目前在薪资上IC设计要比FP…

Vue3返回顶部组件及返回顶部js封装

介绍 vue3中,封装监听页面滚动的js, 及页面滚动到一定像素时,显示返回顶部的按钮,点击按钮会有放大的动画,并逐渐滚动到顶部的组件。效果如下: 代码 封装js,监听屏幕滚动事件,以及是否显示返回顶部的按钮; 在项目目录下新建 utils文件夹,并在该文件夹下创建index.…

国外SEO优化的重要性及应对策略

SEO是指搜索引擎优化&#xff0c;是一种通过优化网站的结构和内容&#xff0c;提高网站在搜索引擎中的排名&#xff0c;从而吸引更多的流量和潜在客户的过程。 国外SEO优化尤为重要&#xff0c;因为搜索引擎在全球范围内广泛使用&#xff0c;而谷歌是全球最受欢迎的搜索引擎之…

java Math类 和 System类 详解(通俗易懂)

Math类介绍Math类常用方法及演示System类简介System类常用方法及演示一、前言本节内容是我们《API-常用类》专题的第四小节了。本节内容主要讲Math类和System类&#xff0c; 内容包括Math类介绍、Math类常用方法、System类介绍&#xff0c;System类常用方法。该小节内容基本不涉…

【教程】你现在还不知道微软的New Bing?你out了,快点进来看

哈喽啊&#xff0c;大家好&#xff0c;好久不见&#xff0c;我是木易巷&#xff01; 不禁感叹&#xff0c;AI人工智能时代真的已经来临&#xff01; 目前&#xff0c;谷歌和微软就各自面向大众的产品发布了重大公告。谷歌推出了一款名为Bard实验性对话式 AI 服务&#xff0c;而…

Python开发入门之了解Python高阶函数

上段时间有小伙伴询问&#xff1a;高阶函数的问题&#xff0c;今天小编就带大家一起来看一看&#xff1a; 一、什么是高阶函数? 高阶函数是在Python中一个非常有用的功能函数&#xff0c;所谓高阶函数就是一个函数可以用来接收另一个函数作为参数&#xff0c;这样的函数叫做…

扬帆优配|数字经济刮起“东风”,龙头晋级7连板

今日两市共40只涨停股&#xff0c;主要集中于数字经济、6G板块&#xff0c;上一个交易日涨停股为29股&#xff1b;除掉18只ST股及3只一字板新股&#xff0c;共19股涨停。另外&#xff0c;4股封板未遂&#xff0c;整体封板率为83%。 6股封单金额超亿元 从收盘涨停板封单量来看&…

第54章 图片URL的后端获取

1 注意&#xff1a; 在.NetCore WebApi框架中&#xff0c;在默认情况下由于没有集成“UseStaticFiles”内置管道中间件方法&#xff0c;如果想要通过图片URL显示图片&#xff0c;由会显示“404”错误&#xff0c;必须先把“UseStaticFiles”内置管道中间件方法集成到.NetCore W…

安装MySQL数据库8.0服务实例

前言 之前尝试去安装了MySQL5.7的社区版本&#xff0c;今天来安装MySQL8.0的版本&#xff0c;并且以两种方式进行安装&#xff0c;一个是通过RPM包的安装&#xff0c;另一个则是编译的方式。 一. 前期准备 查看服务器IP [rootlocalhost ~]# hostname -I 192.168.161.166 19…