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

    浏览量

    12238
  • 数组
    +关注

    关注

    1

    文章

    409

    浏览量

    25593

原文标题:不懂就问!

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

收藏 人收藏

    评论

    相关推荐

    树与二叉树的定义

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

    快速排序(2)#数据结构

    数据函数二叉树
    未来加油dz
    发布于 :2023年09月05日 09:58:17

    循环链表和双向链表(2)#数据结构

    数据函数二叉树
    未来加油dz
    发布于 :2023年09月05日 09:52:24

    平衡二叉树(3)#数据结构

    数据函数二叉树
    未来加油dz
    发布于 :2023年09月05日 09:45:06

    平衡二叉树(2)#数据结构

    数据函数二叉树
    未来加油dz
    发布于 :2023年09月05日 09:43:54

    平衡二叉树(1)#数据结构

    数据函数二叉树
    未来加油dz
    发布于 :2023年09月05日 09:42:30

    希尔排序(2)#数据结构

    数据函数二叉树
    未来加油dz
    发布于 :2023年09月05日 09:41:08

    哈希表及哈希函数的构造(2)#数据结构

    数据函数二叉树
    未来加油dz
    发布于 :2023年09月05日 09:29:03

    哈希表及哈希函数的构造(1)#数据结构

    数据函数二叉树
    未来加油dz
    发布于 :2023年09月05日 09:27:23

    单源最短路径-迪杰斯特拉算法(3)#数据结构

    数据函数二叉树
    未来加油dz
    发布于 :2023年09月05日 09:25:38

    二叉树二叉树的性质(3)#数据结构

    数据函数二叉树
    未来加油dz
    发布于 :2023年09月05日 09:09:51

    二叉树二叉树的性质(2)#数据结构

    数据函数二叉树
    未来加油dz
    发布于 :2023年09月05日 09:08:32

    二叉树二叉树的性质(1)#数据结构

    数据函数二叉树
    未来加油dz
    发布于 :2023年09月05日 09:06:44

    二叉排序树(2)(2)#数据结构

    数据函数二叉树
    未来加油dz
    发布于 :2023年09月05日 09:04:56

    这么简单的二叉树算法都不会?

    这个题目是leetcode的第572题,要求是这样的:给定两颗二叉树A和B,判断B是否是A的子树。
    的头像 发表于 08-29 11:19 508次阅读
    这么简单的<b class='flag-5'>二叉树</b>算法都不会?