代码随想录算法训练营第十五天|102.二叉树的层序遍历、226.翻转二叉树、101.对称二叉树

102.二叉树的层序遍历

102.二叉树的层序遍历

讲透二叉树的层序遍历 | 广度优先搜索 | LeetCode:102.二叉树的层序遍历

代码随想录(programmercral.com)

思路

使用队列辅助完成层序遍历,先将根节点入队,然后进行循环处理,一直处理到队列为空为止,处理的逻辑为,首先获取队列元素的个数(这个操作的含义为,统计当前层有多少个元素),然后对这些元素进行处理,每个元素的处理逻辑为先访问该节点,然后看他的左孩子是否为空,是入队,不是看右孩子是否为空,是就入队,不是处理下一个元素,直到这些元素处理完,说明处理完一层,就该处理下一层了,逻辑同上,直到队列为空,也就是所有层都处理完了,完成层序遍历。

代码实现

/**

* 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.翻转二叉树

229.翻转二叉树

听说一位巨佬面Google被拒了,因为没写出翻转二叉树 | LeetCode:226.翻转二叉树

代码随想录(programmercral.com)

方法一

可以使用层序遍历,每次访问节点的时候就把他的左右子树颠倒

代码实现

/**

* 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.对称二叉树

101.对称二叉树

新学期要从学习二叉树开始! | LeetCode:101. 对称二叉树

代码随想录(programmercral.com)

思路

采用后序遍历,原因是要根据孩子节点的对比结果来判断左右子树是否堆成,因为后续遍历左右根的特性,左右子树节点一定会先访问,然后吧结果返回给根节点,所以可以采用后序遍历。具体处理过程为:传入要判断是否为对称二叉树的树的左子树和右子树,然后左子树的判断条件是左右根,右子树是右左根,因为先判断最外侧的节点是否相等,然后再判断内侧的节点是否相等,反映到树上就是左子树先访问左子树,右子树先访问右子树。总共可能碰到五种情况,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);

}

};

总结

掌握了层序遍历的写法,但是由于时间原因,只写了一道层序遍历的题,以后有时间需要补,同时明白了,前序中序后序其实只是处理逻辑,不一定非要那样遍历才是前序中序后序遍历,同时后序有一个美好性质就是,最后处理根,可以获得其孩子节点的处理结果。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值