赞
踩
对应题目
102.二叉树的层序遍历
107.二叉树的层次遍历II
199.二叉树的右视图
637.二叉树的层平均值
429.N叉树的层序遍历
515.在每个树行中找最大值
116.填充每个节点的下一个右侧节点指针
117.填充每个节点的下一个右侧节点指针II
104.二叉树的最大深度
111.二叉树的最小深度
二叉树的层序遍历 相当于图论里的广度优先搜索 (队列实现)
二叉树的递归遍历 相当于图论里的深度优先搜索
- 题目描述: 给你二叉树的根节点 root ,返回其节点值 自底向上的层序遍历 。 (即按从叶子节点所在层到根节点所在的层,逐层从左向右遍历)。
1、通过队列保存每一层里遍历过的元素
2、对队列里的每一层元素数量size进行记录,因为队列里存放的数可能有第二层的也有可能有第三层的
3、在第二层元素弹出的同时,将其左右孩子(第三层)也同时加入队列,遍历完第二层所有元素之后,其实第三层所有元素都已在队列里,记录第三层元素数量
4、终止条件:队列里没有元素->遍历完
/** * 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<vector<int>> levelOrder(TreeNode* root) { queue<TreeNode*> que; // 栈记录根节点 以及弹出之后其左右孩子节点 vector<vector<int>>result; //二维数组记录结果 层数以及 if(root!=NULL)que.push(root); while(!que.empty()){ int size = que.size(); vector<int> 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); } return result; } };
- 题目描述: 给你二叉树的根节点 root ,返回其节点值 自底向上的层序遍历 。 (即按从叶子节点所在层到根节点所在的层,逐层从左向右遍历)。
1、在102二叉树的层序遍历结果的基础上进行翻转
/** * 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<vector<int>> levelOrderBottom(TreeNode* root) { queue<TreeNode*>que; vector<vector<int>>result; if(root!=NULL)que.push(root); while(!que.empty()){ int size = que.size(); vector<int>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; } };
- 题目描述:给定一个二叉树的 根节点 root,想象自己站在它的右侧,按照从顶部到底部的顺序,返回从右侧所能看到的节点值。
1、本来的思路为 一路向右 每次添加 根节点 以及其右孩子 以及右孩子的右孩子 如果右孩子的右孩子不存在 返回右孩子的左孩子,但是忽略了以下情况:第三层最右的元素不是接在上个最右元素的下面
2、正确思路为层序遍历的时候,根据size判断是否遍历到单层最后面的元素
/** * 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<int> rightSideView(TreeNode* root) { queue<TreeNode*>que; // 存放根节点 以及其对应的左右孩子 vector<int>result; if(root!=NULL)que.push(root); while(!que.empty()){ int size = que.size(); while(size--){ TreeNode* node = que.front(); que.pop(); if(size==0)result.push_back(node->val); // 将每层最后一个元素放入result if(node->left)que.push(node->left); if(node->right)que.push(node->right); } } return result; } };
- 题目描述:给定一个非空二叉树的根节点 root , 以数组的形式返回每一层节点的平均值。与实际答案相差 10-5 以内的答案可以被接受。
1、利用sum计算每层的和 注意精度!!! 无论是result 还是记录的sum 以及avr都要用 double
/** * 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<double> averageOfLevels(TreeNode* root) { queue<TreeNode*>que; vector<double>result; if(root!=NULL)que.push(root); while(!que.empty()){ int size = que.size(); int resize = size; vector<int>vec; double sum = 0; while(size--){ TreeNode* node = que.front(); que.pop(); sum += (node->val); if(node->left)que.push(node->left); if(node->right)que.push(node->right); } double avr = sum/resize; result.push_back(avr); } return result; } };
- 题目描述:给定一个 N 叉树,返回其节点值的层序遍历。(即从左到右,逐层遍历)。
- 树的序列化输入是用层序遍历,每组子节点都由 null 值分隔(参见示例)。
1、N叉树中,一个节点有多个孩子,注意定义队列的类型不再是TreeNode* 而是Node*
2、在原来对于左右孩子的判断中,将节点孩子加入队列,节点孩子的数量为 children.size()
,指针所对应的孩子为 node->children[i]
/* // 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; vector<vector<int>>result; if(root!=NULL)que.push(root); while(!que.empty()){ int size = que.size(); vector<int>vec; while(size--){ 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; } };
- 题目描述:给定一棵二叉树的根节点 root ,请找出该二叉树中每一层的最大值。
1、定义maxnum为最小值INT32_MIN,因为-2^31 <= Node.val <= 2^31 - 1,有负数
2、注意条件运算符的用法 条件?满足条件返回值或运算:不满足返回值或运算
/** * 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<int> largestValues(TreeNode* root) { queue<TreeNode*>que; vector<int>result; if(root!=NULL)que.push(root); while(!que.empty()){ int size = que.size(); int maxnum = INT32_MIN; while(size--){ TreeNode* node = que.front(); que.pop(); int num = node->val; maxnum = maxnum<num ? num : maxnum; if(node->left)que.push(node->left); if(node->right)que.push(node->right); } result.push_back(maxnum); } return result; } };
- 题目描述:给定一个 完美二叉树 ,其所有叶子节点都在同一层,每个父节点都有两个子节点。二叉树定义如下:
- 填充它的每个 next 指针,让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点,则将 next 指针设置为 NULL。
- 初始状态下,所有 next 指针都被设置为 NULL。
1、在单层遍历的时候记录一下本层的头部节点,然后在遍历的时候让前一个节点指向本节点
2、每一层中,头部节点指针的next指向本层的下一个元素,本层的最后一个元素所对应的next指针为NULL
3、难点:定义一个Node* node , Node* nodepre
,在对于nodepre赋值时,记得要
node = nodepre
, 为了之后对于node的左右孩子入队列。
/* // 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<Node*>que; if(root!=NULL)que.push(root); while(!que.empty()){ int size = que.size(); Node* node; Node* nodepre; for(int i=0;i<size;i++){ if(i==0){ nodepre = que.front(); // 头节点为nodepre que.pop(); node = nodepre; }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; // 最后一个节点指向NULL } return root; } };
- 题目描述:给定一个二叉树:
- 填充它的每个 next 指针,让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点,则将 next 指针设置为 NULL 。
- 初始状态下,所有 next 指针都被设置为 NULL 。
1、让这个指针指向其下一个右侧节点,与116的区别在于 此题说的是二叉树,但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<Node*>que; if(root!=NULL)que.push(root); while(!que.empty()){ int size = que.size(); Node* node; Node* nodepre; 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; nodepre = nodepre->next; } if(node->left)que.push(node->left); if(node->right)que.push(node->right); } nodepre->next = NULL; } return root; } };
- 题目描述:给定一个二叉树,找出其最小深度。
- 最小深度是从根节点到最近叶子节点的最短路径上的节点数量。
- 说明:叶子节点是指没有子节点的节点。
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: int minDepth(TreeNode* root) { queue<TreeNode*>que; int mindep = 0; if(root!=NULL)que.push(root); while(!que.empty()){ int size = que.size(); mindep++; TreeNode* node; while(size--){ 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 mindep; } } return mindep; } };
- 题目描述:给定一个二叉树,找出其最大深度。
- 二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。
- 说明: 叶子节点是指没有子节点的节点。
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: int maxDepth(TreeNode* root) { queue<TreeNode*>que; int depth = 0; if(root!=NULL)que.push(root); while(!que.empty()){ int size = que.size(); depth++; TreeNode* node; while(size--){ node = que.front(); que.pop(); if(node->left)que.push(node->left); if(node->right)que.push(node->right); } } return depth; } };
- 题目描述: 给你一棵二叉树的根节点 root ,翻转这棵二叉树,并返回其根节点。
/** * 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) { queue<TreeNode*>que; if(root!=NULL)que.push(root); while(!que.empty()){ int size = que.size(); while(size--){ TreeNode* node = que.front(); que.pop(); swap(node->left,node->right);// 把每个节点的左右孩子翻转 if(node->left)que.push(node->left); if(node->right)que.push(node->right); } } return root; } };
- 题目描述: 给你一个二叉树的根节点 root , 检查它是否轴对称。
1、
1、若用层序遍历 只判断 新存入的vec 数值是否对称相等 就忽略了位置的对称性。
/** * 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: bool isSymmetric(TreeNode* root) { if(root==NULL)return true; queue<TreeNode*>que; que.push(root->left); // 左子树头节点 que.push(root->right); // 右子树头节点 while(!que.empty()){ TreeNode* leftNode = que.front();que.pop(); TreeNode* rightNode = que.front();que.pop(); if(!leftNode && !rightNode)continue; // 左右节点都为空 说明对称 // 左右一个节点不为空 或者都不为空但是数值不相等 if(!leftNode || !rightNode ||(leftNode->val != rightNode->val)){ return false; } que.push(leftNode->left); que.push(rightNode->right); que.push(leftNode->right); que.push(rightNode->left); } return true; } };
NULL与 nullptr
1、了解层序遍历的模板之后,对于做以下题轻松很多
2、针对二叉树问题,解题时分清用前中后序遍历还是层序遍历。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。