代码随想录打卡第十五天 | 二叉树2 层序遍历 | leetcode226&101

目录

226 -  翻转二叉树

思路

实现方式1、深度优先

实现方式2、广度优先

提交代码

101 - 对称二叉树

思路

实现方式1、广度优先

实现方式2、深度优先-递归

226 -  翻转二叉树

思路

交换每个子树的左右节点

实现方式1、深度优先

使用递归,先处理左子树,再处理右子树;

举例:

4,2,7,1,3,6,9

处理顺序:

根节点:4

4的左右子树:2,7交换        

7的左右子树:6,9交换        //左子树处理完成

9的左右子树:null, null交换       //return null;

6的左右子树:null, null交换         //return null;

至此左子树处理完成;

2的左右子树:1,3交换        

3的左右子树:null,null交换         //return null

1的左右子树:null,null交换        //return null        

至此右子树处理完成;

实现方式2、广度优先

一层一层处理遍历,从上往下;

举例:

 4,2,7,1,3,6,9

处理顺序:

根节点压入队列queue:4

取出queue.front(), 4的left,right压入队列;

使用取出的front()交换2,7,第二层交换完成                            队列元素:7,2

取出7. 压入6,9,交换6,9                                                         队列元素:2,9,6

取出2,压入1,3,交换1,3, 第三层交换完成                         队列元素:9,6,3,1

取出9,不压入队列        队列元素:6,3,1

取出6,不压入队列        队列元素:3,1

取出3,不压入队列        队列元素:1

取出1,不压入队列        队列元素:

队列空,循环结束;

提交代码


#include <regex>
#include "queue"

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) {}
};

using namespace std;
class CinvertTree {
public:
//    1、递归,深度优先算法
//    TreeNode* invertTree(TreeNode* root) {
//        if(root == nullptr) return nullptr;
//        else
//        {
//            swap(root->left, root->right);
//            if(root->left)  invertTree(root->left);
//            if(root->right)  invertTree(root->right);
//        }
//        return root;
//    }

//  2、模拟栈,广度优先,遍历每个节点,并交换
    TreeNode* invertTree(TreeNode* root) {
        if(root == nullptr) return nullptr;
        {
            queue<TreeNode*> Q;
            Q.push(root);
            while(!Q.empty()){
                TreeNode *node = Q.front();
                Q.pop();
                if(node->left)  Q.push(node->left);
                if(node->right)  Q.push(node->right);
                swap(node->left, node->right);
            }
        }
        return root;
    }
};

101 - 对称二叉树

思路

对比对称位置元素是否相等,相等则继续往下对比,不等返回false;

实现方式1、广度优先

使用deque,因为对称需要对比对一个元素和最后一个元素;deque可从前后访问;

 

处理顺序:

压入root        队列元素:1

取出front,back, pop_front, pop_back(需先对队列判空,因为队列只有一个元素时,pop_front之后队列已空,不能使用pop_back),

比较front和back,相等为空continue,不等返回false;
                          相等不为空,分别push_front,push_back;        //队列元素2,2,2,2(这里取出来的front和back都是根节点,所有分别把左右子树都压入了队列,会多比较一次但不影响最终结果

取出front,back2(2 == 2),

        1、push_front(4),push_front(3)队列前面压入front的右节点4,再压入front节点3,                  2、push_back(3),push_back(4)队列后面压入front的左节点3,再压入front右节点4       //队列元素3,4,2,2,4,3(压入顺序需保证压入队列后还是原来树的对称关系

取出front,back3,3(3 == 3)

        1、两个3的左右子树都为空,不压入元素        队列元素:4,2,2,4

取出front,back4,4(4 == 4)

        1、两个4的左右子树都为空,不压入元素        队列元素:2,2

取出front,back2,2(2 == 2)        //到这里其实已经遍历完成所有节点了,但是因为之前把根节点当两个节点了,导致还需要再遍历一遍整个树,整个树相当于遍历了两遍,这里可以优化

        1、2,2的子树不为空,按之前规则压入3,4,4,3        队列元素:3,4,4,3

......

实现方式2、深度优先-递归

实现一个方法,传入需要对比的两个元素root->left, root->right,一直递归到整个树完成;

因为leetcode给的isSymmetric方法只有一个参数TreeNode* root,所以要自己写一个有两个参数的函数,分别传入左右两个节点:root->left,root->right,从第二层开始遍历,可以规避实现方式1的那种把根节点当两个节点使用的情况,使遍历的节点数减少一倍;

#include <deque>
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) {}
};
using namespace std;
class CisSymmetric {
public:
//    1、自己实现,deque,前后第一个和最后一个对比
//    bool isSymmetric(TreeNode* root) {
//        if(root == nullptr) return true;
//        deque<TreeNode*> dq;
//        dq.push_back(root);
//        while(!dq.empty()){
//            TreeNode* front = dq.front();
//            TreeNode* back = dq.back();
//            dq.pop_front();
//            if(!dq.empty())
//                dq.pop_back();
//
//            if((front == nullptr && back != nullptr) ||
//                    back == nullptr && front != nullptr)    //1空1不空
//                return false;
//            else if(front == nullptr && back == nullptr){   //2都为空
//                continue;
//            }
//
//            //2都不空
//            dq.push_front(front->right);
//            dq.push_front(front->left);
//            dq.push_back(back->left);
//            dq.push_back(back->right);
//
//            if(front->val != back->val){
//                return false;
//            }
//
//        }
//        return true;
//    }

//  2、递归实现
    bool isSymmetric(TreeNode* root) {
        if (!root)
            return true;
        return isTwoTreesSymmetric(root->left, root->right);
    }

    bool isTwoTreesSymmetric(TreeNode* r1, TreeNode* r2) {
        if (!r1 && !r2)
            return true;
        if (r1 && r2 && r1->val == r2->val)
            return isTwoTreesSymmetric(r1->left, r2->right) && isTwoTreesSymmetric(r1->right, r2->left);
        return false;
    }

    void test()
    {
        TreeNode n1(2);
        TreeNode n2(3);
        TreeNode n3(3);
        TreeNode n4(4);
        TreeNode n5(5);
//        TreeNode n6(4);
        TreeNode n7(4);
        n1.left = &n2;
        n1.right = &n3;

        n2.left = &n4;
        n2.right = &n5;

        n3.left = nullptr;
        n3.right = &n7;

        bool b = isSymmetric(&n1);
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

铁中棠ang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值