当前位置: 首页 > news >正文

LeetCode用数组建立二叉树

1.需求

在LeetCode上刷到二叉树相关的题目时,发现题目中都没法直接给出二叉树结构,而是给一个数组,现在需要利用这个数组构建起二叉树的结构。

2.分析

首先分析一下LeetCode上给的数组有什么规律,以110题平衡二叉树为例
请添加图片描述
这里不难看出数组里面的两个null,是9的两个子节点,为了清楚的指明树的结构(15、7是20的子节点而不是9的子节点),这里必须记录两个null

请添加图片描述
同样的道理观察第二个例子,发现这个数组里面的两个null是前面2的子节点,但是最右侧的3却没有给出两个null的子节点。这是为什么呢?

3.结论:

首先给出的数组大致依据肯定是层序遍历,但是单纯一个层序遍历的数组肯定不能唯一声明一个二叉树,所以一定要做特殊处理,就是把一些必要的null塞进数组,但是到底哪些null必须写进去,这里我根据我构建二叉树的代码,总结了几点要求。

(1).除最底层外的结点外,仅有单个子节点或者没有子结点的,必须把子节点记为null写入数组。(参见例1)

(2).如果数组最后两位是null,则省略。

比如例3,把右侧结点3的子节点记为null的话,数组为 [1,2,2,3,3,null,null,4,4,null,null],最后两位是null,所以省略。
至于省略的原因,在构建二叉树的代码中,空结点是不入队列的,而最后两个结点时null的话也就意味着处理完前面地结点后,队列就空了,没有需要处理的了,所以可以省略。

(3).不要补全成为完全二叉树

请添加图片描述
如果把例3这样补全成完全二叉树,数组[1,2,2,3,3,null,null,4,4,null,null,null,null,null,null] ,这样当然可以唯一声明一个二叉树,但是对于一些斜二叉树来说,这样做很浪费空间,完全可以优化。况且代码中空结点不入队列,这样做的话需要给空结点赋予空的左右结点,是错误的。

4.原理

这里使用一个先进先出的结构队列queue,先将头结点入队,每次将队头结点出队,就将后面两个结点入队,这两个入队的就是刚才出队结点的左右子节点。

5.代码

最后给出代码段

#include <vector>
#include <string>
#include <queue>
using namespace std;

//二叉树结点结构
struct TreeNode {
	int val;
	TreeNode* left;
	TreeNode* right;
	TreeNode() :val(0), left(nullptr), right(nullptr) {}
	TreeNode(int x) :val(x), left(nullptr), right(nullptr) {}
	TreeNode(int x, TreeNode* left, TreeNode* right) :val(x), left(left), right(right) {}
};

TreeNode* createBinaryTree(vector<string> nodes) {
	int len = nodes.size();

	if (len == 0) {
		return NULL;
	}

	if (nodes[0] == "null") {
		return nullptr;
	}

	TreeNode* root;
	//建立结点队列并将根节点入队
	queue<TreeNode*> nodesQue;
	root = new TreeNode(stoi(nodes[0]));
	nodesQue.push(root);

	//loc遍历数组,每次取两个结点
	for (int loc = 1; loc < len; loc = loc + 2) {
		//获取结点并出队
		TreeNode* node = nodesQue.front();
		nodesQue.pop();
		
		//获取队头结点的左右结点
		string left = nodes[loc];
		string right = nodes[loc + 1];

		//赋予左右结点
		if (left == "null") {
			node->left = nullptr;
		}
		else {
			node->left = new TreeNode(stoi(left));
			nodesQue.push(node->left);
		}

		if (right == "null") {
			node->right = nullptr;
		}
		else {
			node->right = new TreeNode(stoi(right));
			nodesQue.push(node->right);
		}
	}
	return root;
}

相关文章:

  • Leetcode560. 和为 K 的子数组
  • Docker部署Tomcat
  • NFT交易量下滑 传统品牌布局热情未衰
  • 2022下半年各省软考报名费用汇总,不知道的看这里
  • 社交网络的数据挖掘与分析,什么是社交网络分析
  • Allegro DVT与SiMa.ai携手优化嵌入式边缘应用的能效
  • 2022-8-30 第七小组 学习日记 (day54)JavaWeb、Servlet、HTTP-请求 响应、乱码问题
  • U9二次开发之BE插件开发
  • 推荐系统-Hive基础
  • 通信原理 | 基本概念:信源、信道、噪声、信宿等
  • 关于Flask高级_RequestParser中的add_argument方法参数详解
  • flume系列之:基于zookeeper部署flume agent升级guava和curator版本
  • 触摸控件——滑动调节
  • NetApp与VMware和AWS合作,帮助客户实现云端企业工作负载的现代化和扩展
  • 快来了解一下5个超实用的WPS表格操作技巧!
  • 【跃迁之路】【463天】刻意练习系列222(2018.05.14)
  • Akka系列(七):Actor持久化之Akka persistence
  • Angularjs之国际化
  • ES学习笔记(12)--Symbol
  • express如何解决request entity too large问题
  • Fundebug计费标准解释:事件数是如何定义的?
  • golang中接口赋值与方法集
  • GraphQL学习过程应该是这样的
  • Java,console输出实时的转向GUI textbox
  • JavaScript对象详解
  • JAVA多线程机制解析-volatilesynchronized
  • JS基础之数据类型、对象、原型、原型链、继承
  • maven工程打包jar以及java jar命令的classpath使用
  • Netty 4.1 源代码学习:线程模型
  • Python3爬取英雄联盟英雄皮肤大图
  • React as a UI Runtime(五、列表)
  • Swoft 源码剖析 - 代码自动更新机制
  • Windows Containers 大冒险: 容器网络
  • 回流、重绘及其优化
  • 解决jsp引用其他项目时出现的 cannot be resolved to a type错误
  • 开源地图数据可视化库——mapnik
  • 前端技术周刊 2018-12-10:前端自动化测试
  • 使用 Xcode 的 Target 区分开发和生产环境
  • 世界编程语言排行榜2008年06月(ActionScript 挺进20强)
  • 收藏好这篇,别再只说“数据劫持”了
  • 阿里云API、SDK和CLI应用实践方案
  • 好程序员大数据教程Hadoop全分布安装(非HA)
  • ​VRRP 虚拟路由冗余协议(华为)
  • # Python csv、xlsx、json、二进制(MP3) 文件读写基本使用
  • # 手柄编程_北通阿修罗3动手评:一款兼具功能、操控性的电竞手柄
  • #pragma pack(1)
  • #我与虚拟机的故事#连载20:周志明虚拟机第 3 版:到底值不值得买?
  • (2.2w字)前端单元测试之Jest详解篇
  • (2015)JS ES6 必知的十个 特性
  • (2020)Java后端开发----(面试题和笔试题)
  • (5)STL算法之复制
  • (C语言)strcpy与strcpy详解,与模拟实现
  • (python)数据结构---字典
  • (二)c52学习之旅-简单了解单片机
  • (二)WCF的Binding模型