二叉树专题
二叉树的常用术语
根节点:没有父节点的节点
叶节点:没有子节点的节点
边:连接节点之间的线段
节点所在层:从顶至底递增,顶层为1
节点的度:拥有的子节点的数量
二叉树的高度:从根节点到最远节点的边的长度
节点的深度:该节点到根节点的边的长度
节点的高度:该节点到最远节点的边的长度
前序,中序,后序遍历(递归遍历)
判断方法:从根节点的遍历顺序查找,前序遍历从根节点开始,根,左,右;中序遍历从左下节点开始 左,根,又;后续节点顺序为 左,右,根
/**
* 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:
void digui(TreeNode* node,vector<int>& vec)//前序遍历
{
if(node == nullptr) return;
vec.push_back(node->val);
digui(node->left,vec);
digui(node->right,vec);
}
void digui(TreeNode* node,vector<int>& vec)//中序遍历
{
if(node == nullptr) return;
digui(node->left,vec);
vec.push_back(node->val);
digui(node->right,vec);
}
void digui(TreeNode* node,vector<int>& vec)//后序遍历
{
if(node == nullptr) return;
digui(node->left,vec);
digui(node->right,vec);
vec.push_back(node->val);
}
vector<int> preorderTraversal(TreeNode* root) {
vector<int> res;
digui(root,res);
return res;
}
};
层序遍历
思路:从上至下,从左至右依次遍历
代码:
class Solution {
public:
vector<vector<int>> levelOrder(TreeNode* root) {
queue<TreeNode *>que;
que.push(root);
vector<vector<int>> res;
if(root == nullptr)
{
return res;
}
while(!que.empty())
{
int n = que.size();//后面的队列长度在不断变化
vector<int> current;
for(int i = 0;i < n;i++)
{
TreeNode* node = que.front();
que.pop();
current.push_back(node->val);
if(node->left != nullptr)
{
que.push(node->left);
}
if(node->right != nullptr)
{
que.push(node->right);
}
}
res.push_back(current);
}
return res;
}
};
代码:
class Solution {
public:
vector<vector<int>> levelOrderBottom(TreeNode* root) {
queue<TreeNode *>que;
que.push(root);
vector<vector<int>> res;
if(root == nullptr) return res;
while(!que.empty())
{
int n = que.size();
vector<int> current;
for(int i = 0; i < n;i++)
{
TreeNode* node = que.front();
que.pop();
current.push_back(node->val);
if(node->left != nullptr)
{
que.push(node->left);
}
if(node->right != nullptr)
{
que.push(node->right);
}
}
res.insert(res.begin(),current);//与自上而下遍历的区别就在这:每次把current插入res的后面而非前面
}
return res;
}
};
代码:
class Solution {
public:
vector<int> rightSideView(TreeNode* root) {
queue<TreeNode *>que;
que.push(root);
vector<int> res;
if(root == nullptr) return res;
while(!que.empty())
{
int n = que.size();
vector<int> current;
for(int i = 0;i < n;i++)
{
TreeNode* node = que.front();
que.pop();
current.push_back(node->val);
if(node->left != nullptr)
{
que.push(node->left);
}
if(node->right != nullptr)
{
que.push(node->right);
}
}
res.push_back(current[current.size() - 1]);//每次只存储current最右边的数
}
return res;
}
};
代码:
class Solution {
public:
vector<double> averageOfLevels(TreeNode* root) {
queue<TreeNode *>que;
que.push(root);
vector<double> res;
if(root == nullptr) return res;
while(!que.empty())//每一层不为空
{
int n = que.size();//每一层的节点数
double avg;//注意数字类型
vector<int> current;//存储该层的所有节点的值,从左往右
for(int i = 0;i < n;i++)
{
TreeNode* node = que.front();
que.pop();
current.push_back(node->val);
if(node->left != nullptr)
{
que.push(node->left);
}
if(node->right != nullptr)
{
que.push(node->right);
}
double sum = 0;
for(int i = 0; i < current.size();i++)
{
sum += current[i];
}
avg = sum / current.size();
}
res.push_back(avg);
}
return res;
}
};
需要注意:二叉树的构造函数不是left和right左右节点,而是使用数组存储的children指针
代码:
/*
// 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) {
queue<Node* > que;
que.push(root);
vector<vector<int>> res;
if(root == nullptr) return res;
while(!que.empty())
{
int n = que.size();
vector<int> current;
for(int i = 0;i < n;i++)
{
Node* node = que.front();
que.pop();
current.push_back(node->val);
for(auto children : node->children)//遍历node节点中的children指针
{
if(children != nullptr)
{
que.push(children);
}
}
}
res.push_back(current);
}
return res;
}
};
515. 在每个树行中找最大值 - 力扣(LeetCode)
代码:
class Solution {
public:
vector<int> largestValues(TreeNode* root) {
queue<TreeNode* > que;
que.push(root);
vector<int> res;
if(root == nullptr) return res;
while(!que.empty())
{
int n = que.size();
vector<int> vec;
for(int i = 0;i < n;i ++)
{
TreeNode* node = que.front();
que.pop();
vec.push_back(node->val);
if(node->left != nullptr)
{
que.push(node->left);
}
if(node->right != nullptr)
{
que.push(node->right);
}
}
sort(vec.begin(),vec.end());
res.push_back(vec[vec.size() - 1]);
}
return res;
}
};