0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

怎么就能构造成二叉树呢?

算法与数据结构 来源:代码随想录 作者:代码随想录 2022-07-14 11:20 次阅读
经常有录友问,二叉树的题目中输入用例,在ACM模式下应该怎么构造呢?

力扣上的题目,输入用例就给了一个数组,怎么就能构造成二叉树呢?

这次就给大家好好讲一讲!

就拿最近公众号上 二叉树的打卡题目来说:

538.把二叉搜索树转换为累加树

其输入用例,就是用一个数组来表述 二叉树,如下:

768cf948-0323-11ed-ba43-dac502259ad0.png

一直跟着公众号学算法的录友 应该知道,我在二叉树:构造二叉树登场!,已经讲过,只有 中序与后序 和 中序和前序 可以确定一颗唯一的二叉树。前序和后序是不能确定唯一的二叉树的

那么538.把二叉搜索树转换为累加树的示例中,为什么,一个序列(数组或者是字符串)就可以确定二叉树了呢?

很明显,是后台直接明确了构造规则。

再看一下 这个 输入序列 和 对应的二叉树。768cf948-0323-11ed-ba43-dac502259ad0.png

从二叉树 推导到 序列,大家可以发现这就是层序遍历。

但从序列 推导到 二叉树,很多同学就看不懂了,这得怎么转换呢。

我在关于二叉树,你该了解这些!已经详细讲过,二叉树可以有两种存储方式,一种是 链式存储,另一种是顺序存储。

链式存储,就是大家熟悉的二叉树,用指针指向左右孩子。

顺序存储,就是用一个数组来存二叉树,其方式如图所示:

76b93ed6-0323-11ed-ba43-dac502259ad0.png

那么此时大家是不是应该知道了,数组如何转化成 二叉树了。如果父节点的数组下标是i,那么它的左孩子下标就是i * 2 + 1,右孩子下标就是 i * 2 + 2

那么这里又有同学疑惑了,这些我都懂了,但我还是不知道 应该 怎么构造。

来,咱上代码。昨天晚上 速度敲了一遍实现代码。

具体过程看注释:

//根据数组构造二叉树
TreeNode*construct_binary_tree(constvector<int>&vec){
vectorvecTree(vec.size(),NULL);
TreeNode*root=NULL;
//把输入数值数组,先转化为二叉树节点数组
for(inti=0;i< vec.size(); i++) {
        TreeNode* node = NULL;
if(vec[i]!=-1)node=newTreeNode(vec[i]);//数组中用-1表示null
vecTree[i]=node;
if(i==0)root=node;
}
//遍历一遍,根据规则左右孩子赋值就可以了
//注意这里结束规则是i*2+2< vec.size(),避免空指针
for(inti=0;i*2+2< vec.size(); i++) {
        if(vecTree[i]!=NULL){
//线性存储转连式存储关键逻辑
vecTree[i]->left=vecTree[i*2+1];
vecTree[i]->right=vecTree[i*2+2];
}
}
returnroot;
}

这个函数最后返回的 指针就是 根节点的指针, 这就是 传入二叉树的格式了,也就是 力扣上的用例输入格式,如图:

76cd1ece-0323-11ed-ba43-dac502259ad0.png

也有不少同学在做ACM模式的题目,就经常疑惑:

  • 让我传入数值,我会!
  • 让我传入数组,我会!
  • 让我传入链表,我也会!
  • 让我传入二叉树,我懵了,啥?传入二叉树?二叉树怎么传?

其实传入二叉树,就是传入二叉树的根节点的指针,和传入链表都是一个逻辑。

这种现象主要就是大家对ACM模式过于陌生,说实话,ACM模式才真正的考察代码能力(注意不是算法能力),而 力扣的核心代码模式 总有一种 不够彻底的感觉。

所以,如果大家对ACM模式不够了解,一定要多去练习!

那么以上的代码,我们根据数组构造二叉树,接来下我们在 把 这个二叉树打印出来,看看是不是 我们输入的二叉树结构,这里就用到了层序遍历,我们在二叉树:层序遍历登场!中讲过。

完整测试代码如下:

#include
#include
#include
usingnamespacestd;

structTreeNode{
intval;
TreeNode*left;
TreeNode*right;
TreeNode(intx):val(x),left(NULL),right(NULL){}
};

//根据数组构造二叉树
TreeNode*construct_binary_tree(constvector<int>&vec){
vectorvecTree(vec.size(),NULL);
TreeNode*root=NULL;
for(inti=0;i< vec.size(); i++) {
        TreeNode* node = NULL;
if(vec[i]!=-1)node=newTreeNode(vec[i]);
vecTree[i]=node;
if(i==0)root=node;
}
for(inti=0;i*2+2< vec.size(); i++) {
        if(vecTree[i]!=NULL){
vecTree[i]->left=vecTree[i*2+1];
vecTree[i]->right=vecTree[i*2+2];
}
}
returnroot;
}

//层序打印打印二叉树
voidprint_binary_tree(TreeNode*root){
queueque;
if(root!=NULL)que.push(root);
vector<vector<int>>result;
while(!que.empty()){
intsize=que.size();
vector<int>vec;
for(inti=0;i< size; i++) {
            TreeNode* node = que.front();
            que.pop();
            if(node!=NULL){
vec.push_back(node->val);
que.push(node->left);
que.push(node->right);
}
//这里的处理逻辑是为了把null节点打印出来,用-1表示null
elsevec.push_back(-1);
}
result.push_back(vec);
}
for(inti=0;i< result.size(); i++) {
        for(intj=0;j< result[i].size(); j++) {
            cout<< result[i][j] << "";
}
cout<< endl;
}
}

intmain(){
//注意本代码没有考虑输入异常数据的情况
//用-1来表示null
vector<int>vec={4,1,6,0,2,5,7,-1,-1,-1,3,-1,-1,-1,8};
TreeNode*root=construct_binary_tree(vec);
print_binary_tree(root);
}

可以看出我们传入的数组是:{4,1,6,0,2,5,7,-1,-1,-1,3,-1,-1,-1,8} , 这里是用 -1 来表示null,

538.把二叉搜索树转换为累加树中的输入是一样的

768cf948-0323-11ed-ba43-dac502259ad0.png

这里可能又有同学疑惑,你这不一样啊,题目是null,你为啥用-1。

用-1 表示null为了方便举例,如果非要和 力扣输入一样一样的,就是简单的字符串处理,把null 替换为 -1 就行了。

在来看,测试代码输出的效果:

76ef3fae-0323-11ed-ba43-dac502259ad0.png

可以看出和 题目中输入用例 这个图 是一样一样的。只不过题目中图没有把 空节点 画出来而已。

7747e866-0323-11ed-ba43-dac502259ad0.png

大家可以拿我的代码去测试一下,跑一跑。

注意:我的测试代码,并没有处理输入异常的情况(例如输入空数组之类的),处理各种输入异常,大家可以自己去练练

审核编辑 :李倩


声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 二叉树
    +关注

    关注

    0

    文章

    74

    浏览量

    12307
  • 数组
    +关注

    关注

    1

    文章

    413

    浏览量

    25893

原文标题:不懂就问!

文章出处:【微信号:TheAlgorithm,微信公众号:算法与数据结构】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    什么是默克尔(Merkle Tree)?如何计算默克尔根?

    01 默克尔的概念 默克尔(Merkle Tree)是一种特殊的二叉树,它的每个节点都存储了一个数据块的哈希值。哈希值是一种可以将任意长度的数据转换为固定长度的字符串的算法,它具有唯一性和不可
    的头像 发表于 09-30 18:22 559次阅读
    什么是默克尔<b class='flag-5'>树</b>(Merkle Tree)?如何计算默克尔根?

    工控一体机构造及可能会发生的问题

    大家或许都对工业平板电脑有所耳闻,那么,对于它的主要构造部分,我们又了解多少?熟悉这些部件,有助于我们在设备出现故障时,迅速定位问题所在。
    的头像 发表于 08-25 16:52 970次阅读

    指电极上覆盖敏感材料的阻值计算

    覆盖的敏感材料厚度超出指厚度时计算电阻,是否可以视作指电极指间电阻多个周期串联后与超出指厚度部分敏感材料电阻并联
    发表于 07-05 14:48

    指MOSFET器件静电防护鲁棒性提升技巧

    栅极接地NMOS是一种广泛应用的片上ESD器件结构,为达到特定ESD防护等级,一般会采用多指版图形式来减小器件占用的芯片面积。但是,多指栅极接地NMOS在ESD应力作用下,各个指难于做到均匀
    的头像 发表于 06-22 00:50 469次阅读
    多<b class='flag-5'>叉</b>指MOSFET器件静电防护鲁棒性提升技巧

    原理图设计里两颗重要的(国产EDA)

    原理图里面两颗重要的,那就是元件和网络,作为EDA工具中的重要视图和概念,虽然看似枯燥,但它们扮演着非常重要的角色,它们为电路图的层次化结构提供了有力支撑。想象一个大型的电路设计项目,就像一个
    的头像 发表于 05-29 17:47 658次阅读
    原理图设计里两颗重要的<b class='flag-5'>树</b>(国产EDA)

    时钟的图好像是APB的时钟都是AHB给的,请问这些时钟为多少是哪儿配的?是sysinit里吗?

    大家好,我看时钟的图好像是APB的时钟都是AHB给的,请问这些时钟为多少是哪儿配的?是sysinit里吗?
    发表于 05-11 07:34

    串联的总线舵机是不是只用一个UART接口就能控制

    串联的总线舵机是不是只用一个UART接口就能控制
    发表于 03-07 06:30

    哈夫曼编码怎么算 哈夫曼编码左边是0还是1

    二叉树,将出现频率高的字符用较短的编码表示,而出现频率低的字符则用较长的编码表示。通过这种方式,可以实现对数据进行高效的编码和解码。 下面我们将详细介绍哈夫曼编码的算法过程。 统计字符频率 在进行哈夫曼编码前,首先需
    的头像 发表于 01-30 11:27 2506次阅读

    AD5060的VOUT输出是否就能直接用于产品的对外输出

    请问各位: 我现在用AD5060设计一个0-5V输出的模块,输出信号由普通的电压信号采集器采集,这种应用,AD5060的VOUT之后还需要设计电压跟随器之类的处理电路吗? AD5060的VOUT输出是否就能直接用于产品的对外输出
    发表于 12-25 06:34

    如何修改内核设备

    如何修改内核设备
    的头像 发表于 12-14 14:06 760次阅读
    如何修改内核设备<b class='flag-5'>树</b>

    时钟是什么?介绍两种时钟树结构

    今天来聊一聊时钟。首先我先讲一下我所理解的时钟是什么,然后介绍两种时钟树结构。
    的头像 发表于 12-06 15:23 1577次阅读

    数字IC设计中的分段时钟综合

    为什么需要分段去做时钟?因为在某些情况下,按照传统的方法让每一个clock group单独去balance,如果不做额外干预,时钟天然是做不平的。
    的头像 发表于 12-04 14:42 1816次阅读
    数字IC设计中的分段时钟<b class='flag-5'>树</b>综合

    堆的实现思路

    什么是堆? 堆是一种 基于树结构的数据结构,它是一棵二叉树 ,具有以下两个特点: 堆是一个完全二叉树,即除了最后一层,其他层都是满的,最后一层从左到右填满。 堆中每个节点都满足堆的特性,即父节点的值
    的头像 发表于 11-24 16:02 387次阅读
    堆的实现思路

    二叉树的定义

    型结构 是一类重要的 非线性数据结构 ,其中以二叉树最为常用,直观来看,是以分支关系定义的层次结构。型结构在客观世界中广泛存在,比
    的头像 发表于 11-24 15:57 1256次阅读
    <b class='flag-5'>树</b>与<b class='flag-5'>二叉树</b>的定义

    OP-TEE安全存储安全文件的格式

    时,默认情况下, 加密后的数据会被保存在/data/tee目录中。 安全存储功能使用 二叉树的方式来 保存加密后的文件。 当第一次使用安全存储功能创建用于保存敏感数据的安全文件时,OP-TEE将会在/data/tee目录中生成两个文件:dirf.db文件和以数字命名的文件。 dirf.db文
    的头像 发表于 11-21 11:49 724次阅读
    OP-TEE安全存储安全文件的格式