LeetCode | 102.二叉树的层次遍历
这次来写一下 LeetCode 的第 102 题,二叉树的层次遍历。
题目描述
题目直接从 LeetCode 上截图过来,题目如下:
上面的题就是 二叉树的层次遍历 题目的截图,同时 LeetCode 会根据选择的语言给出一个类的定义或者函数的定义,然后在其中实现 二叉树的层次遍历 的解题过程。这次我使用 C++ 语言来进行完成。
C++ 语言给出的函数定义如下:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
vector<vector<int>> levelOrder(TreeNode* root) {
}
};
通过函数定义可以看出,levelOrder 函数的参数是一个二叉树的根节点,然后返回的值是一个二维数组,我们要做的就是按照层次来遍历这个二叉树,并且将二叉树每层的值需要保存在二维数组中并返回。
问题分析
该题目是一个比较好理解的题目,因为题目中已经明确了需要使用层次遍历二叉树来得到每个节点上的值,且不同层次上节点的数据保存在不同的数组中,最后每个层次的数组构成一个二维数组。
拿题目中给出的例子来说明什么是层次遍历,如下图。
在图中,3 是第一层,9 和 20 是第二层,15 和 7 是第三层,通过遍历这个二叉树按层次来分别把它们保存到不同的数组中,最后构成一个二维数组返回。
二叉树的层次遍历需要使用另外一个数据结构来协助进行遍历,另外的那个数据结构就是“队列”。队列的作用是保留每一层的从左到右的顺序,进而使得我们在进行层次遍历的时候,可以按照从左往右的顺序完成层次遍历。
首先在遍历之前,使根节点先进入队列,队列中有了根节点后,就可以进入循环。进入循环后,首先获取队头的元素,并让队头元素出队,目前也就是根节点,通过出队的元素分别得到它的左孩子和右孩子,并让它的左孩子和右孩子进入临时队列(有可能左孩子和右孩子不同时存在,反正存在哪个哪个进入队列即可)。然后保存当前节点的元素到数组中。然后临时队列中的元素,进入真正要进行循环获取层次的队列,队列中始终要保持只有当前层次的节点。
由于篇幅有限,可能无法很好的把其方式描述清楚,但是看代码会很直观。
代码实现
C++ 的代码如下:
/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */class Solution {public: vector<vector<int>> levelOrder(TreeNode* root) {
vector<vector<int>> vec;
if (root == NULL) { return vec; }
// 队列保存树的根节点 queue<TreeNode*> que; que.push(root);
while (!que.empty()) { // 保存当前层上节点的值 vector<int> v; // 临时队列 queue<TreeNode*> tmp;
while (!que.empty()) { TreeNode *p = que.front(); que.pop();
// 左右节点入队 if (p->left) { tmp.push(p->left); } if (p->right) { tmp.push(p->right); }
v.push_back(p->val); }
// 下一层的节点入队 while (!tmp.empty()) { que.push(tmp.front()); tmp.pop(); }
vec.push_back(v); }
return vec; }};
从代码中可以看出,整个代码是一个两层 while 循环,外层的 while 循环用来遍历整颗二叉树,内层 while 循环是用来遍历二叉树相同层的每个节点。代码中,我引入了两个队列,分别是 que 和 tmp,que 队列是用来进行遍历当前层的每个节点的,tmp 队列是用来临时保存当前层的左孩子和右孩子节点的。
提交结果
在写完代码后,点击右下角的 “执行代码”,然后观察 “输出” 和 “预期结果” 是否一致,一致的话就点击 “提交” 按钮。点击 “提交” 按钮后,系统会使用更多的测试用例来测试我们写的函数体,如果所有的测试用例都通过了,那么就会给出 “通过” 的字样,如果没有通过,会给出失败的那一组测试用例,我们可以根据给出的测试用例来继续修改代码。我们的代码提交后的截图如下:
类似这样需要引入其他数据结构辅助完成的题目,我个人觉得使用 C 语言就比较难,就拿这道题目来说,层次遍历二叉树本身就是两层的 while 循环了,还要引入队列去辅助完成,像 C 语言这样没有现成的集合可以使用,我还要自己去完成一个队列的数据结构去进行管理么?不知道有什么好的方法。
- [接口测试 - 基础篇] 07 来来来,一起读写excel玩玩之一
- 时间序列分析算法【R详解】
- 【专知-关关的刷题日记16】Leetcode 88. Merge Sorted Array
- [接口测试 - 基础篇] 06 好吧也来解析下html
- [接口测试 - 基础篇] 05 好讨厌的xml解析
- 【专知-关关的刷题日记17】Leetcode 268. Missing Number
- 【专知-关关的刷题日记18】Leetcode 35. Search Insert Position
- [接口测试 - http.client篇] 15 常用API说明及基本的示例
- [接口测试 - http.client篇] 14 源码初探及其工作机制分析
- 【专知-关关的刷题日记19】Leetcode 118. Pascal's Triangle
- 每周学点大数据 | No.3算法设计与分析理论
- HDU 1874 畅通工程续【Floyd算法实现】
- 接口测试 | 21 基于flask弄个restful API服务出来
- 数论部分第二节:埃拉托斯特尼筛法 埃拉托斯特尼筛法
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- android 设置wallpaper的操作方法
- R语言作图不显示中文解决办法,如何使用中文字体
- Android OKHTTP的单例和再封装的实例
- Android 自定义返回按钮的实例详解
- Android在layout xml中使用ViewStub完成动态加载问题
- Android编程中Intent实现页面跳转功能详解
- Android编程之桌面小部件AppWidgetProvider用法示例
- Android编程实现悬浮窗获取并显示当前内存使用量的方法
- Android ListView中动态添加RaidoButton的实例详解
- Android沉浸式状态栏设计的实例代码
- Android编程使用LinearLayout和PullRefreshView实现上下翻页功能的方法
- R语言使用bootstrap和增量法计算广义线性模型(GLM)预测置信区间
- Android 中两个Activity 之间的传值问题
- 学习使用Material Design控件(二)使用DrawerLayout实现侧滑菜单栏效果
- Android Spinner列表选择框的应用