102.二叉树的层序遍历
讲透二叉树的层序遍历 | 广度优先搜索 | LeetCode: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>> levelOrder(TreeNode* root) {
queue<TreeNode*> que;
if(root!=nullptr) que.push(root);
vector<vector<int>> result;
while(!que.empty()){
int size=que.size();
vector<int> vec;
for(int i=0;i<size;i++){
TreeNode* p=que.front();
que.pop();
vec.push_back(p->val);
if(p->left) que.push(p->left);
if(p->right) que.push(p->right);
}
result.push_back(vec);
}
return result;
}
};
229.翻转二叉树
听说一位巨佬面Google被拒了,因为没写出翻转二叉树 | LeetCode: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:
void swap(TreeNode* node){
TreeNode* temp=node->left;
node->left=node->right;
node->right=temp;
}
TreeNode* invertTree(TreeNode* root) {
queue<TreeNode*> que;
if(root!=nullptr) que.push(root);
while(!que.empty()){
int size=que.size();
for(int i=0;i<size;i++){
TreeNode* node=que.front();
que.pop();
swap(node);
if(node->left) que.push(node->left);
if(node->right) que.push(node->right);
}
}
return root;
};
方法二
同样也是遍历一个节点就把他的左右指针互换,中序遍历不可以使用(理论上可以使用)是因为,中序处理顺序是左1根右1,先处理左子树,再处理根,处理根的时候换成了右2根左2,这时候按照中序遍历的逻辑该处理左2了(也就是右子树)但是左2已经处理过了,实际上该处理的是右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:
void swap(TreeNode* node){
TreeNode* temp=node->left;
node->left=node->right;
node->right=temp;
}
TreeNode* invertTree(TreeNode* root) {
//使用后序遍历反转二叉树
if(root==nullptr) return root;
swap(root);
invertTree(root->left);
invertTree(root->right);
return root;
}
101.对称二叉树
新学期要从学习二叉树开始! | LeetCode:101. 对称二叉树
思路
采用后序遍历,原因是要根据孩子节点的对比结果来判断左右子树是否堆成,因为后续遍历左右根的特性,左右子树节点一定会先访问,然后吧结果返回给根节点,所以可以采用后序遍历。具体处理过程为:传入要判断是否为对称二叉树的树的左子树和右子树,然后左子树的判断条件是左右根,右子树是右左根,因为先判断最外侧的节点是否相等,然后再判断内侧的节点是否相等,反映到树上就是左子树先访问左子树,右子树先访问右子树。总共可能碰到五种情况,1.左子树不空,右子树为空,返回false,2.左子树为空,右子树不空,返回false,3.左子树为空,右子树为空,返回true,4.左子树不空,右子树不空,值不相等,返回false。5.左子树右子树值相等。
代码实现
/**
* 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 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!=NULL&&right!=NULL&&left->val!=right->val) return false;//左右都不为空但值不相等,而且由于上面处理了全空的情况,所以不用担心出现操作空指针的情况
else return compare(left->left,right->right) &&compare(left->right,right->left);
}
bool isSymmetric(TreeNode* root) {
if(root==nullptr) return true;
return compare(root->left,root->right);
}
};
总结
掌握了层序遍历的写法,但是由于时间原因,只写了一道层序遍历的题,以后有时间需要补,同时明白了,前序中序后序其实只是处理逻辑,不一定非要那样遍历才是前序中序后序遍历,同时后序有一个美好性质就是,最后处理根,可以获得其孩子节点的处理结果。