Day11 OK,补打卡!第十一天
以下是今日份的总结
102.二叉树的层序遍历
107.二叉树的层次遍历II
199.二叉树的右视图
637.二叉树的层平均值
429.N叉树的层序遍历
515.在每个树行中找最大值
116.填充每个节点的下一个右侧节点指针
117.填充每个节点的下一个右侧节点指针II
102|107|116|117|199|429|515|637|层序遍历的递归和迭代法非常重要 ^ _ ^
二叉树的层序遍历
思路:
按照二叉树从上到下的顺序一层一层的向下遍历
值得注意的是
辅助队列对此帮助很大
迭代:
vector<vector<int>> levelOrderBottom(TreeNode* root) {
vector<vector<int>> v;
queue<TreeNode*> que;
if (root == NULL)
return v;
que.push(root);
while (!que.empty()) {
vector<int> vec;
for (int i = que.size(); i > 0; i--) {
root = que.front(); // 当前根节点是队列里的头位
que.pop(); // 出队
vec.push_back(root->val);
if (root->left != NULL) {
que.push(root->left); // 有左节点就入队
}
if (root->right != NULL) {
que.push(root->right); // 有右节点就入队
}
}
v.push_back(vec); // 把该层节点集放入容器
}
return v;
}
递归:
void order(TreeNode* node,vector<vector<int>> &vec,int depth){
if(node ==nullptr) return;
if(vec.size()==depth) vec.push_back(vector<int>());
vec[depth].push_back(node->val);
order(node->left, vec,depth+1);
order(node->right, vec,depth+1);
}
vector<vector<int>> levelOrderBottom(TreeNode* root) {
int depth = 0;
vector<vector<int>>result;
order(root, result, depth);
return result;
}
二叉树的层序遍历 II
思路:
自下而上,层序遍历,reverse
值得注意的是
reverse()
迭代:
vector<vector<int>> levelOrderBottom(TreeNode* root) {
vector<vector<int>> v;
queue<TreeNode*> que;
if (root == NULL)
return v;
que.push(root);
while (!que.empty()) {
vector<int> vec;
for (int i = que.size(); i > 0; i--) {
root = que.front(); // 当前根节点是队列里的头位
que.pop(); // 出队
vec.push_back(root->val);
if (root->left != NULL) {
que.push(root->left); // 有左节点就入队
}
if (root->right != NULL) {
que.push(root->right); // 有右节点就入队
}
}
v.push_back(vec); // 把该层节点集放入容器
}
reverse(v.begin(), v.end());
return v;
}
递归:
void order(TreeNode* node,vector<vector<int>> &vec,int depth){
if(node ==nullptr) return;
if(vec.size()==depth) vec.push_back(vector<int>());
vec[depth].push_back(node->val);
order(node->left, vec,depth+1);
order(node->right, vec,depth+1);
}
vector<vector<int>> levelOrderBottom(TreeNode* root) {
int depth = 0;
vector<vector<int>>result;
order(root, result, depth);
reverse(result.begin(), result.end());
return result;
}
二叉树的右视图
思路:
层序遍历,但是只将每层最后一位加入vector
值得注意的是
对根结点为NULL的情况要注意判断
迭代:
vector<int> rightSideView(TreeNode* root) {
queue<TreeNode*> que;
vector<int> res;
if (root != nullptr) que.push(root);
while (!que.empty()) {
int levelSize = que.size();
for (int i = 0; i < levelSize; ++i) {
TreeNode* currentNode = que.front();
que.pop();
if (i == levelSize - 1) {
res.push_back(currentNode->val);
}
if (currentNode->left != nullptr) {
que.push(currentNode->left);
}
if (currentNode->right != nullptr) {
que.push(currentNode->right);
}
}
}
return res;
}
二叉树的层平均值
思路:
层序遍历,然后对每一层的节点值做平均值处理
值得注意的是
节点值为double方便平均值计算
迭代:
vector<double> averageOfLevels(TreeNode* root) {
queue<TreeNode*>que;
if(root !=NULL) que.push(root);
vector<double> vd;
while(!que.empty()){
int size = que.size();//队列长度
double sum = 0;//当前层节点值总和
for(int i = 0;i<size;i++){
TreeNode* node = que.front();
sum+=node->val;
que.pop();//中
if(node->left)que.push(node->left);//左
if(node->right)que.push(node->right);//右
}
vd.push_back(sum/size);//压入平均值
}
return vd;
}
递归:
void order(TreeNode* node,vector<vector<double>> &vec,int depth){
if(node == nullptr)return;
if(vec.size() == depth) vec.push_back(vector<double>());
vec[depth].push_back(node->val);
order(node->left,vec,depth+1);
order(node->right,vec,depth+1);
}
vector<double> averageOfLevels(TreeNode* root) {
vector<vector<double>> vd;
vector<double>v;
int depth = 0;
order(root,vd,depth);
for(int i = 0;i<vd.size();i++){
double vall =0;
for(double val:vd[i]){
vall +=val;
}
v.push_back(vall/vd[i].size());
}
return v;
}
N叉树的层序遍历
思路:
和二叉树的层序遍历一样,在递归部分把left、right替换成children的遍历
值得注意的是
子节点不再最多为两个
迭代:
vector<vector<int>> levelOrder(Node* root) {
queue<Node*> que;
if (root != NULL) que.push(root);
vector<vector<int>> result;
while (!que.empty()) {
int size = que.size();
vector<int> 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;
}
递归:
void order(Node* node,vector<vector<int>>&vec,int depth){
if(node==nullptr)return;
if(vec.size()==depth) vec.push_back(vector<int>());
vec[depth].push_back(node->val);//压入当前节点值
vector<Node*>v;
v = node->children;
//替换了二叉树左右子树递归
for(int i = 0;i<v.size();i++){
order(v[i],vec,depth+1);
}
}
vector<vector<int>> levelOrder(Node* root) {
vector<vector<int>>result;
int depth = 0;
order(root,result,depth);
return result;
}
在每个树行中找最大值
思路:
层序遍历,但是在途中对每一层的节点元素做比较,记录最大值
值得注意的是
节点存在负值
迭代:
vector<int> largestValues(TreeNode* root) {
queue<TreeNode*>que;
vector<int>res;
if(root!=NULL){
que.push(root);
}
while(!que.empty()){
int size = que.size();
int maxValue = INT_MIN;//树的value要考虑到有负值
for(int i = 0;i<size;i++){
TreeNode* node = que.front();
que.pop();
maxValue = std::max(maxValue,node->val);
if(node->left)que.push(node->left);
if(node->right)que.push(node->right);
}
res.push_back(maxValue);
}
return res;
}
递归:
void levelOrder(TreeNode* node,vector<vector<int>>&vec,int depth){
if(node==nullptr)return;
if(depth==vec.size()){
vec.push_back(vector<int>());
}
vec[depth].push_back(node->val);
levelOrder(node->left, vec, depth+1);
levelOrder(node->right, vec, depth+1);
}
vector<int> largestValues(TreeNode* root) {
vector<vector<int>> res;
vector<int>result;
int depth = 0;
levelOrder(root, res, depth);
for(vector<int>cur:res){
int max = 0 ;
for(int i = 0;i<cur.size();i++){
if(i==0){
max=cur[0];
continue;
}
max = std::max(max,cur[i]);
}
result.push_back(max);
}
return result;
}
填充每个节点的下一个右侧节点指针
本题讨论的是完全二叉树,但是解题方法按一般情况来看,可以覆盖完全二叉树。
思路:
层序遍历,然后对节点的next进行指向
值得注意的是
当前层末尾的节点指向NULL
迭代:
Node* connect(Node* root) {
queue<Node*> que;
if (root != NULL) que.push(root);
while (!que.empty()) {
int size = que.size();
// vector<int> vec;
Node* nodePre;
Node* node;
for (int i = 0; i < size; i++) {
if (i == 0) {
nodePre = que.front(); // 取出一层的头结点
que.pop();
node = nodePre;
} else {
node = que.front();
que.pop();
nodePre->next = node; // 本层前一个节点next指向本节点
nodePre = nodePre->next;
}
if (node->left) que.push(node->left);
if (node->right) que.push(node->right);
}
nodePre->next = NULL; // 本层最后一个节点指向NULL
}
return root;
}
递归:
void order(Node* node,vector<vector<Node*>>& vec,int depth){
if(node==nullptr)return;
if(depth==vec.size())vec.push_back(vector<Node*>());
vec[depth].push_back(node);
order(node->left, vec, depth+1);
order(node->right,vec,depth+1);
}
Node* connect(Node* root) {
if(root==nullptr)return root;
vector<vector<Node*>> vec;
//Node* res = new Node();
int depth = 0;
order(root, vec, depth);
for(vector<Node*>tmp:vec){
for(int i = 0;i<tmp.size();i++){
if(i==tmp.size()-1)tmp[i]->next=NULL;
else{
tmp[i]->next=tmp[i+1];
}
}
}
return root;
}
填充每个节点的下一个右侧节点指针 II
思路:
层序遍历,然后对节点的next进行指向
值得注意的是
当前层末尾的节点指向NULL
迭代:
Node* connect(Node* root) {
queue<Node*> que;
if (root != NULL) que.push(root);
while (!que.empty()) {
int size = que.size();
vector<int> vec;
Node* nodePre;
Node* node;
for (int i = 0; i < size; i++) {
if (i == 0) {
nodePre = que.front(); // 取出一层的头结点
que.pop();
node = nodePre;
} else {
node = que.front();
que.pop();
nodePre->next = node; // 本层前一个节点next指向本节点
nodePre = nodePre->next;
}
if (node->left) que.push(node->left);
if (node->right) que.push(node->right);
}
nodePre->next = NULL; // 本层最后一个节点指向NULL
}
return root;
}
递归:
void order(Node* node,vector<vector<Node*>>& vec,int depth){
if(node==nullptr)return;
if(depth==vec.size())vec.push_back(vector<Node*>());
vec[depth].push_back(node);
order(node->left, vec, depth+1);
order(node->right,vec,depth+1);
}
Node* connect(Node* root) {
if(root==nullptr)return root;
vector<vector<Node*>> vec;
int depth = 0;
order(root, vec, depth);
for(vector<Node*>tmp:vec){
for(int i = 0;i<tmp.size();i++){
if(i==tmp.size()-1)tmp[i]->next=NULL;
else{
tmp[i]->next=tmp[i+1];
}
}
}
return root;
}
写在最后
----OK,今日份的博客就写到这里,这一期的题全是层序遍历,明天继续加油!!!
—看了看下期的题,以后的二叉树就没这么轻松了;
–追上时间进度了吗?如追,从欠四天变成欠三天!!(笑
-风从我脚边溜走,没有告别。