1.对称二叉树
给定一个二叉树,检查它是否是镜像对称的。
方法一:递归。
如果一个树的左子树和右子树镜像对称,那么这个树是对称的。
class Solution {
public:
bool check(TreeNode* p,TreeNode* q){
if(p==NULL&&q==NULL) return true;
if(p==NULL||q==NULL) return false;//p,q中有一个是空指针,一个不是,则返回false
return (p->val==q->val)&&check(p->left,q->right)&&check(p->right,q->left);
}
bool isSymmetric(TreeNode* root) {
return check(root,root);
}
};
方法二:迭代。
首先引入队列,这是把递归程序改写为迭代程序的常用方法。参考官方题解:
初始化时我们把根节点入队两次。每次提取两个结点并比较它们的值(队列中每两个连续的结点应该是相等的,而且它们的子树互为镜像),然后将两个结点的左右子结点按相反的顺序插入队列中。当队列为空时,或者我们检测到树不对称(即从队列中取出两个不相等的连续结点)时,该算法结束。
class Solution {
public:
bool check(TreeNode *u, TreeNode *v) {
queue <TreeNode*> q;
q.push(u); q.push(v);
while (!q.empty()) {
u = q.front(); q.pop();
v = q.front(); q.pop();
if (!u && !v) continue;
if ((!u || !v) || (u->val != v->val)) return false;
q.push(u->left);
q.push(v->right);
q.push(u->right);
q.push(v->left);
}
return true;
}
bool isSymmetric(TreeNode* root) {
return check(root, root);
}
};
作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/symmetric-tree/solution/dui-cheng-er-cha-shu-by-leetcode-solution/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
层次遍历二叉树。
void LevelTraverse(TreeNode* root){//层次遍历
if(root==NULL) return;
TreeNode* temp=nullptr;
queue <TreeNode*> q;
q.push(root);
while(!q.empty()){
temp=q.front();
cout<<temp->val<<" "; q.pop();
if(temp->left!=NULL) q.push(temp->left);
if(temp->right!=NULL) q.push(temp->right);
}
cout<<endl;
}
2.二叉树的最大深度
广度优先搜索的方法。C++的queue类的成员函数有:push() pop() size() empty() front() back(). 参考官方题解:
我们也可以用「广度优先搜索」的方法来解决这道题目,但我们需要对其进行一些修改,此时我们广度优先搜索的队列里存放的是「当前层的所有节点」。每次拓展下一层的时候,不同于广度优先搜索的每次只从队列里拿出一个节点,我们需要将队列里的所有节点都拿出来进行拓展,这样能保证每次拓展完的时候队列里存放的是当前层的所有节点,即我们是一层一层地进行拓展,最后我们用一个变量 ans 来维护拓展的次数,该二叉树的最大深度即为 ans。
class Solution {
public:
int maxDepth(TreeNode* root) {
int ans=0;
if(root==NULL) return 0;
queue<TreeNode*> q;
q.push(root);
while(!q.empty()){
int sz=q.size();
while(sz>0){
TreeNode* node=q.front();q.pop();
if(node->left) q.push(node->left);
if(node->right) q.push(node->right);
sz=sz-1;
}
ans=ans+1;
}
return ans;
}
};
3.二叉树的层序遍历
可以借鉴上一道题目的写法,用队列的结构和两层循环。
方法一:BFS
class Solution {
public:
vector<vector<int>> levelOrder(TreeNode* root) {
vector<vector<int>> array;
if(root==NULL) return array;
queue<TreeNode*> q;
vector<int> d;
q.push(root);
while(!q.empty()){
int sz=q.size();
while(sz>0){
TreeNode* node=q.front();q.pop();
d.push_back(node->val);
if(node->left) q.push(node->left);
if(node->right) q.push(node->right);
sz=sz-1;
}
array.push_back(d);
d.clear();
}
return array;
}
};
方法二:一个最朴素的算法是用(node,level)来表示节点的状态。
4.二叉树的锯齿形遍历
5.二叉树的层平均值
可以使用DFS的递归和非递归的形式;或者BFS。使用递归的DFS执行效率不如BFS。
class Solution {
public:
vector<double> averageOfLevels(TreeNode* root){
vector<double> res;
vector<int> count;
average(root,0,res,count);
for(int i=0;i<res.size();i++)
res[i]=res[i]/count[i];
return res;
}
void average(TreeNode* t,int i,vector<double> &sum,vector<int> &count){//sum和count数组会被修改
//需要额外记录当前节点所在高度
if(t==NULL) return;
if(i<sum.size()){
sum[i]=sum[i]+t->val;
count[i]=count[i]+1;
}
else{//i=0的话
sum.push_back(1.0*t->val);
count.push_back(1);
}
average(t->left,i+1,sum,count);
average(t->right,i+1,sum,count);
}
};