OK,今天学习的内容主要是二叉树广度优先遍历,就是层序遍历,而利用的基本数据结构就是队列,下面直接讲层级遍历:
队列先进先出,符合一层一层遍历的逻辑,所以我们用队列,下面我们直接用的代码加注释的方式来解释:
Leetcode 102 二叉树的层序遍历
题目链接 二叉树的层级遍历
class Solution {
public:
vector> levelOrder(TreeNode* root) {
//定义队列
queue que;
//只要根节点不为空
if (root != NULL) que.push(root);//就将根节点输入到队列中
vector> result;//遍历结果二维数组(每层多少个,有多少层)
while (!que.empty()) {//停止条件
int size = que.size();//这里是用来确定每一层的节点数目
vector vec;//定义一个一维数组
// 这里一定要使用固定大小size,不要使用que.size(),因为que.size是不断变化的
for (int i = 0; i < size; i++) {
TreeNode* node = que.front();//用node指针来获取我们值,取首节点
que.pop();//弹出
vec.push_back(node->val);//输入到一维数组中
if (node->left) que.push(node->left);//引入弹出节点的左右子节点,空节点忽略
if (node->right) que.push(node->right);
}
result.push_back(vec);//转到二维数组中
}
return result;//输出出来
}
};
附动画图链接:层级遍历
如果这个题目懂了,那么下面这九道题目也就可以做了
107.二叉树的层次遍历II
代码:
/**
* 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) {}
* };
*/
class Solution {
public:
vector> levelOrderBottom(TreeNode* root) {
queue que;
if(root!=NULL){
que.push(root);
}
vector> result;
while(!que.empty()){
int size = que.size();
vector vec;
while(size--){
TreeNode* node = que.front();
que.pop();
vec.push_back(node->val);
if(node->left){
que.push(node->left);
}
if(node->right){
que.push(node->right);
}
}
result.push_back(vec);
}
reverse(result.begin(),result.end());//反转一下,实现自底向上的遍历
return result;
}
};
199.二叉树的右视图
代码:
/**
* 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) {}
* };
*/
class Solution {
public:
vector rightSideView(TreeNode* root) {
queue que;
if(root != NULL){
que.push(root);
}
vectorvec;
while(!que.empty()){
int size = que.size();
for(int i=0;ival);
}
if(node->left){
que.push(node->left);
}
if(node->right){
que.push(node->right);
}
}
}
return vec;
}
};
637.二叉树的层平均值
代码:
/**
* 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) {}
* };
*/
class Solution {
public://注意小数double
vector averageOfLevels(TreeNode* root) {
queue que;
if (root != NULL) que.push(root);
vector result;
while (!que.empty()) {
int size = que.size();
double sum = 0;
for (int i = 0; i < size; i++) {
TreeNode* node = que.front();
que.pop();
sum+=node->val;//直接改成求和
if (node->left) que.push(node->left);
if (node->right) que.push(node->right);
}
result.push_back(sum/size);//绝对值
}
return result;
}
};
429.N叉树的层序遍历
代码:
class Solution {
public://node是对树的定义,treenode是对节点的定义
vector> levelOrder(Node* root) {
queue que;
if (root != NULL) que.push(root);
vector> result;
while (!que.empty()) {
int size = que.size();
vector vec;
for (int i = 0; i < size; i++) {
Node* node = que.front();
que.pop();
vec.push_back(node->val);
for (int i = 0; i < node->children.size(); i++) { // 将节点孩子加入队列
if (node->children[i]) que.push(node->children[i]);//不分左右节点,只要有子节点就输入
}
}
result.push_back(vec);
}
return result;
}
};
515. 在每个树行中找最大值
代码:
/**
* 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) {}
* };
*/
class Solution {
public:
vector largestValues(TreeNode* root) {
queue que;
if (root != NULL) que.push(root);
vector result;
while (!que.empty()) {
int size = que.size();
int maxValue = INT_MIN; // 取每一层的最大值
for (int i = 0; i < size; i++) {
TreeNode* node = que.front();
que.pop();
maxValue = node->val > maxValue ? node->val : maxValue;//最大值比较
if (node->left) que.push(node->left);
if (node->right) que.push(node->right);
}
result.push_back(maxValue); // 把最大值放进数组
}
return result;
}
};
116.填充每个节点的下一个右侧节点指针
这个题目难点在对题目的理解上,如果理解正确,那这道题目就很简单了,也可以跟着代码,把遍历顺序画一遍就明白了
代码:
/*
// Definition for a Node.
class Node {
public:
int val;
Node* left;
Node* right;
Node* next;
Node() : val(0), left(NULL), right(NULL), next(NULL) {}
Node(int _val) : val(_val), left(NULL), right(NULL), next(NULL) {}
Node(int _val, Node* _left, Node* _right, Node* _next)
: val(_val), left(_left), right(_right), next(_next) {}
};
*/
class Solution {
public:
Node* connect(Node* root) {
queue que;
if(root != NULL){
que.push(root);
}
while(!que.empty()){
int size = que.size();
Node*nodePre;
Node*node;
for(int i=0;inext)
}else{
node = que.front();
que.pop();
nodePre->next = node;
nodePre = nodePre->next;
}
if(node->left){
que.push(node->left);
}
if(node->right){
que.push(node->right);
}
}
nodePre->next = NULL;
}
return root;
}
};
117.填充每个节点的下一个右侧节点指针II
换汤不换药,一样的,只是二叉树种类不同,同样适用
代码:
/*
// Definition for a Node.
class Node {
public:
int val;
Node* left;
Node* right;
Node* next;
Node() : val(0), left(NULL), right(NULL), next(NULL) {}
Node(int _val) : val(_val), left(NULL), right(NULL), next(NULL) {}
Node(int _val, Node* _left, Node* _right, Node* _next)
: val(_val), left(_left), right(_right), next(_next) {}
};
*/
class Solution {
public:
Node* connect(Node* root) {
queue que;
if(root != NULL){
que.push(root);
}
while(!que.empty()){
int size = que.size();
vector vec;
Node* nodePre;
Node* node;
for(int i=0;inext = node;
nodePre = nodePre->next;
}
if(node->left){
que.push(node->left);
}
if(node->right){
que.push(node->right);
}
}
nodePre->next = NULL;
}
return root;
}
};
104.二叉树的最大深度
要注意最大深度代表什么:
就是遍历的最大层数,想想什么时候最大就解决了。
代码:
/**
* 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) {}
* };
*/
class Solution {
public:
int maxDepth(TreeNode* root) {
if(root == NULL){
return 0;
}
int depth = 0;
queue que;
que.push(root);
while(!que.empty()){
int size = que.size();
depth++;
for(int i=0;ileft){
que.push(node->left);
}
if(node->right){
que.push(node->right);
}
}
}
return depth;
}
};
111.二叉树的最小深度
和上一道类似,想想什么时候取最小。
代码:
/**
* 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) {}
* };
*/
class Solution {
public:
int minDepth(TreeNode* root) {
if (root == NULL) return 0;
int depth = 0;
queue que;
que.push(root);
while(!que.empty()) {
int size = que.size();
depth++; // 记录最小深度
for (int i = 0; i < size; i++) {
TreeNode* node = que.front();
que.pop();
if (node->left) que.push(node->left);
if (node->right) que.push(node->right);
if (!node->left && !node->right) { // 当左右孩子都为空的时候,说明是最低点的一层了,退出
//谁先到达谁就是最短,并记录了长度
return depth;
}
}
}
return depth;
}
};
Leetcode 226 翻转二叉树
题目链接 226 翻转二叉树
本题目很简单,但是方法也有很多,在这里我只用了递归法:
代码:
/**
* 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) {}
* };
*/
class Solution {
public:
TreeNode* invertTree(TreeNode* root) {
if(root == NULL){
return root;
}
swap(root->left,root->right);
invertTree(root->left);
invertTree(root->right);
return root;
}
};
除了递归法,还有深度优先遍历中的迭代法(前中后都可以)(还有统一的前中后)中序不太推荐,还有广度优先搜索的层级遍历 参考:其他方法
Leetcode 101 对称二叉树
题目链接 101 对称二叉树
本题目如果仔细思考的话,是只能用后序遍历,因为我们要返回的值是root,前序和中序都是左右两边的树节点都没有对比完成就返回是没有可能做对的
下面上递归代码:
class Solution {
public:
bool compare(TreeNode* left, TreeNode* right) {
// 首先排除空节点的情况
if (left == NULL && right != NULL) return false;
else if (left != NULL && right == NULL) return false;
else if (left == NULL && right == NULL) return true;
// 排除了空节点,再排除数值不相同的情况
else if (left->val != right->val) return false;
// 此时就是:左右节点都不为空,且数值相同的情况
// 此时才做递归,做下一层的判断
bool outside = compare(left->left, right->right); // 左子树:左、 右子树:右
bool inside = compare(left->right, right->left); // 左子树:右、 右子树:左
bool isSame = outside && inside; // 左子树:中、 右子树:中 (逻辑处理)
return isSame;
}
bool isSymmetric(TreeNode* root) {
if (root == NULL) return true;
return compare(root->left, root->right);
}
};
迭代法也可以。
今天好累,好迷 end