二叉层序遍历专
狠狠刷十道!
首先知(题目来源力扣 哦~)
**
* Definition for a binary tree node.
* 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) {}
* };
*day14里面已经说过了哈,这是定义二叉数的!
接下来开始喽!
102.二叉树的层序遍历
示例 1:
输入:root = [3,9,20,null,null,15,7]
输出:[[3],[9,20],[15,7]]
示例 2:
输入:root= [1]
输出:[[1]]
示例 3:
输入:root = []
输出:[]
class Solution {
public:
vector<vector<int>> levelOrder(TreeNode* root) {
vector<vector<int>> end;//创建二维数组存结果
queue< TreeNode*> que;//节点队列,quque!
if( root != NULL ) que.push(root);//放入第一个节点在que中
{
while(que.empty() !=0)
{
int size=que.size();//size会改变,这里要把每一次循环的size确定下来
vector<int> floor;//一维来存放每一层floor,最后将一维数组存放入二维数组在
for(int i = 0; i < size; i++)//每次size的值是floor中的值的个数
{
TreeNode* temp=que.front();//杯子存放节点
que.pop();//去除队列节点
floor.push_back(temp->val);//存入一维数组中
//下面是为下层做后续的操作
if(temp->left!=NULL) que.push(temp->left);
if(temp->right!=NULL) que.push(temp->right);
}
end.push_back(floor);//将一维数组存入二维数组,vector的插入为 push_back !!!
}
}
return end;
}
};
107.二叉数的层序遍历 II
给你二叉树的根节点 root ,返回其节点值 自底向上的层序遍历 。 (即按从叶子节点所在层到根节点所在的层,逐层从左向右遍历)
就是第一题的倒叙输出!(体会板子
class Solution {
public:
vector<vector<int>> levelOrderBottom(TreeNode* root) {
vector <vector<int>> end;
queue <TreeNode*> que;
if (root != NULL) que.push(root);//queue插入函数为push!
while(que.empty() !=1 )
{
vector<int> floor;
int size = que.size();
for(int i=0;i<size;i++)
{
TreeNode* temp = que.front();
que.pop();
floor.push_back(temp->val);
if(temp->left != NULL ) que.push(temp->left);//queue插入函数为push!
if(temp->right != NULL ) que.push(temp->right);//queue插入函数为push!
}
end.push_back(floor);
}
reverse(end.begin(), end.end() );//这里是反转,并不是输出值,so直接return是不行的
return end;
}
};
199.二叉树的右视图
给定一个二叉树的 根节点 root,想象自己站在它的右侧,按照从顶部到底部的顺序,返回从右侧所能看到的节点值。
输入: [1,2,3,null,5,null,4]
输出: [1,3,4]
class Solution {
public:
vector<int> rightSideView(TreeNode* root) {
queue<TreeNode*> que;//队列
vector<int> result;
if(root != NULL) que.push(root);
while(que.empty()!=1)
{
int size=que.size();
for(int i=0;i<size;i++)
{
TreeNode* temp = que.front();
que.pop();
if(i == 0) result.push_back(temp->val);//进入队列的顺序不同,i == 不同 ,保证按照次序向vector中传入的是右边的第一个值就行
if(temp->right != NULL) que.push(temp->right);//下一次做准备
if(temp->left != NULL) que.push(temp->left);//做准备
//如果两if交换位置,则i==size即可
}
}
return result;
}
};
637. 二叉树的层平均值
给定一个非空二叉树的根节点 root , 以数组的形式返回每一层节点的平均值。与实际答案相差 10-5 以内的答案可以被接受。
输入:root = [3,9,20,null,null,15,7]
输出:[3.00000,14.50000,11.00000]
解释:第 0 层的平均值为 3,第 1 层的平均值为 14.5,第 2 层的平均值为 11 。
因此返回 [3, 14.5, 11] 。
class Solution {
public:
vector<double> averageOfLevels(TreeNode* root) {//这里定义的是double
vector<double> result;
queue <TreeNode*> que;
if(root != NULL ) que.push(root);
while(que.empty()!=1)//一次while是一层
{
int size=que.size();
double sum=0;//只定义一个变量,简单代码
for(int i=0;i<size;i++)
{
TreeNode* temp =que.front();
que.pop();
sum+=temp->val;
if(temp->left != NULL) que.push(temp->left);
if(temp->right != NULL) que.push(temp->right);
}
result.push_back(sum/size);//巧妙用size(size为每层元素的个数
}
return result;
}
};
429. N 叉树的层序遍历
给定一个 N 叉树,返回其节点值的层序遍历。(即从左到右,逐层遍历)。 树的序列化输入是用层序遍历,每组子节点都由 null 值分隔(参见示例)。
输入:root = [1,null,3,2,4,null,5,6]
输出:[[1],[3,2,4],[5,6]]
这是不是有点难理解哈!是的,只知道思路便可,对于内置函数大一新手不太会哈
// Definition for a Node.
class Node {
public:
int val;
vector<Node*> children;
Node() {}
Node(int _val) {
val = _val;
}
Node(int _val, vector<Node*> _children) {
val = _val;
children = _children;
}
};
*
代码
class Solution {
public:
vector<vector<int>> levelOrder(Node* root) {
vector<vector<int>> result;//二维
queue<Node*>que;//线性队列!!!
if(root!=NULL) que.push(root);
while(!que.empty())
{
vector<int> floor;
int size=que.size();
for(int i=0;i<size;i++)
{
Node* temp=que.front();
que.pop();
floor.push_back(temp->val);
for(int j=0;j<temp->children.size();j++)//这里只是比板子多了个,循环进入队列的过程哈,temp->children.size()各层子成员的size
{
if(temp->children[j]!=NULL) que.push(temp->children[j]);//依次遍历入队
}
}
result.push_back(floor);//一维数组入二维数组
}
return result;
}
};
515. 在每个树行中找最大值
给定一棵二叉树的根节点 root ,请找出该二叉树中每一层的最大值。
class Solution {
public:
vector<int> largestValues(TreeNode* root) {
queue <TreeNode*> que;
vector<int>result;
if(root) que.push(root);
while(!que.empty())
{
int size=que.size();
int MaxVal=INT_MIN;//知道INT_MAX INT_MIN 的含义
for(int i=0;i<size;i++)
{
TreeNode* temp=que.front();
que.pop();
MaxVal=temp->val>MaxVal?temp->val:MaxVal;// 三目运算符求最值的体会学习
//result.push_back(MaxVal);这里不能push,这是for循环,在这一层中maxval还没有比出来
if(temp->left) que.push(temp->left);
if(temp->right) que.push(temp->right);
}
result.push_back(MaxVal);//要在循环遍历之后push maxval;
}
return result;
}
};
值得学习怎么三目运算符求最大值!
怎么定义int的最大最小值!
116.填充每个节点的下一个右侧节点指针(117. 填充每个节点的下一个右侧节点指针 II)
给定一个 完美二叉树 ,其所有叶子节点都在同一层,每个父节点都有两个子节点。二叉树定义如下:
struct Node {
int val;
Node *left;
Node *right;
Node *next;
}
填充它的每个 next 指针,让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点,则将 next 指针设置为 NULL。 初始状态下,所有 next 指针都被设置为 NULL。
输入:root = [1,2,3,4,5,6,7]
输出:[1,#,2,3,#,4,5,6,7,#]
解释:给定二叉树如图 A 所示,你的函数应该填充它的每个 next 指针,以指向其下一个右侧节点,如图 B 所示。序列化的输出按层序遍历排列,同一层节点由 next 指针连接,‘#’ 标志着每一层的结束。
(题目定义好了NULL时输出#)
```cpp
class Solution {
public:
Node* connect(Node* root) {
queue <Node*> que;
//vector<Node*> result; 在原有二叉上修改,不许要重新定义空间
if(root) que.push(root);//再次注意que函数与vec函数push区别
while(!que.empty())
{
int size=que.size();
Node* temp;//取节点
Node* Add_Link;//实现连接的节点
for(int i=0;i<size;i++)
{
if(i==0) {
temp=que.front();//取出头节点!
que.pop();//弹出!
Add_Link=temp;//该节点为第一个节点,目前
} else { //该让temp节点改为这一层的下一个节点了
temp=que.front();//节点向下移一位
que.pop();
Add_Link->next=temp;//Add_Link 节点指向下一个节点(列: 第一节点 -> 第二节点
Add_Link=Add_Link->next;//下移动Add节点
}
if(temp->left) que.push(temp->left);//老演员了,在for循环中为下层做准备
if(temp->right) que.push(temp->right);
}
Add_Link->next=NULL;//完成这一层遍历,最后指向 NULL!
}
return root;
}
};
117. 填充每个节点的下一个右侧节点指针 II也是一样的,只不过我们使用的不是递归,是层序,直接过,建议再手敲一遍代码
104.二叉树的最大深度
3
/ \
9 20
/ \
15 7
最大深度3,也就是高度!
class Solution {
public:
int maxDepth(TreeNode* root) {//注意返回类型已经为 int
int depth=0;//记录深度,也就是高度
queue<TreeNode*>que;
if(root) que.push(root);
while(!que.empty())//一次while代表一层
{
int size=que.size();
depth++;// 一层 加一
TreeNode* temp;
for(int i=0;i<size;i++)
{
temp=que.front();
que.pop();
if(temp->left) que.push(temp->left);
if(temp->right) que.push(temp->right);
}
}
return depth;
}
};
ps:还是板子
111.二叉树的最小深度
给定一个二叉树,找出其最小深度。 最小深度是从根节点到最近叶子节点的最短路径上的节点数量。 说明:叶子节点是指没有子节点的节点。
输入:root = [3,9,20,null,null,15,7]
输出:2
输入:root = [2,null,3,null,4,null,5,null,6]
输出:5
class Solution {
public:
int minDepth(TreeNode* root) {
queue<TreeNode*>que;
if(root) que.push(root);
int depth=0;
while( !que.empty() ){ //+ ()!
TreeNode* temp;
depth++;
int size=que.size();
for(int i=0;i<size;i++)
{
temp=que.front();
que.pop();
if(temp->left) que.push(temp->left);
if(temp->right) que.push(temp->right);
if(temp->left == NULL&& temp->right == NULL)//发现其节点下都为空的节点,说明他为最小的节点,不必循环下层了
return depth;//直接返回
}
}
return depth;
}
};
至此板子ok了