LeetCode[94/100/101]二叉树的中序遍历、相同的树、 对称二叉树 C/C++——Week 2 I

二叉树

1.二叉树的概念

二叉树:n(n≥0)个结点的有限集,或者为(n=0),或者由一个根结点及两棵互不相交的、分别称作该根的左子树右子树二叉树组成。

即使只有一个孩子,也要严格区分左右 。且二叉树和树是两种树结构。

2.二叉树的基本形态

空树、仅有根、左子树为空、右子树为空、左子树与右子树均不为空。

3.二叉树的遍历

遍历:沿某条搜索路径周游二叉树,对每个结点访问一次且仅访问一次。

非线性结构遍历,得到结点按某种次序排列的一个线性序列,所以遍历可看成非线性结构到线性结构的一种映射方法。

二叉树的遍历有两个:层次遍历递归遍历

递归遍历:
如果限定先左后右,则二叉树遍历方式有三种:
前序:DLR、中序:LDR、后序:LRD(此时二叉树由根结点D、左子树L、右子树R构成)。

层次遍历:按二叉树的层序编号的次序访问各结点。

94.二叉树的中序遍历

题目描述[简单]:

给定一个二叉树的根节点 root ,返回 它的 中序 遍历 。

示例1:
示例1

输入:root = [1,null,2,3]
输出:[1,3,2]

思想[递归]:

首先我们先看中序遍历的定义:
若二叉树为空,则空操作返回;
否则:
①中序遍历根结点的左子树;
②访问根结点;
③中序遍历根结点的右子树。
根据其性质,我们要用递归不断套用,很容易写出其代码。

C++代码:

/**
 * 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 inorder(TreeNode* root, vector<int>& r) {
         if(root!=NULL) {
             inorder(root->left, r);	//中根遍历左子树
             r.push_back(root->val);	//访问根,在尾部加入一个数据。
             inorder(root->right, r);	//中根遍历右子树
    }
    }
    vector<int> inorderTraversal(TreeNode* root) { //vector容器是一个模板类,可以存放任何类型的对象
        vector<int> r;
        inorder(root, r);
        return r;
    }
};

时间复杂度:O(n),其中 n 为二叉树节点的个数。二叉树的遍历中每个节点会被访问一次且只会被访问一次。

100.相同的树

题目描述[简单]:

给你两棵二叉树的根节点 p 和 q ,编写一个函数来检验这两棵树是否相同。

如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。

示例1:
1

输入:p = [1,3], q = [1,null,3]
输出:false

思路[递归]:

判断两个树是否相同,实质上是通过遍历两棵树,判断每个子树上的值是否相同。
这里我们最容易想到的是递归法。

本题判断结构相同:
先判断两树的根节点是否相同
两树根节点的左子树和右子树是否相同

判断左子树和右子树相同条件:
左子树的左子树是否相同,右子树的右子树是否相同,一直不同往下走,直到返回结果。

本题的递归条件及其结果为:
当两棵树的遍历到的节点同时为空时,返回 true。
当其中一个为空,另一个非空时,返回 false。
当两个都非空但是值不相等时,返回 false。
如果都相等,就开始就往后遍历,直接有结果或全部遍历完。

C++代码:

/**
 * 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 isSameTree(TreeNode* p, TreeNode* q) {
        if(p == NULL && q == NULL) 
            return true;
        if(p == NULL || q == NULL) 
            return false;
        if(p->val != q->val) 
            return false;
        return isSameTree(p->left, q->left) && isSameTree(p->right, q->right);
    }
};

时间复杂度:O(n) n为遍历结点数。

101.对称二叉树

题目描述[简单]:

给你一个二叉树的根节点 root , 检查它是否轴对称。

示例1:
3

输入:root = [1,2,2,3,4,4,3]
输出:true

思路[递归]:

这几题的思路都是递归,循序渐进理解递归思想。

本题判断是否轴对称
先判断根节点,如果根节点,为空,那么是对称。
如果不为空的话,若左子树与右子树对称,则说明是对称的。

那么判断左子树和右子树对称
就是判断如果左子树的左孩子与右子树的右孩子是否对称,左子树的右孩子与右子树的左孩子是否对称,如果都i对称就说明左子树和右子树是对称的。
这就存在着递归的思想。

本题的递归条件及其结果为:
根节点为空时,返回 true。
往下遍历的两个节点都为空时,返回 true。
往下遍历的两个节点中有一个为空,返回 false。
往下遍历的两个节点的值不相等时,返回 false。
本题递归条件跟上一题差不读,但是递归对象大不相同。

本题递归对象:
左节点的左孩子 和 右节点的右孩子
左节点的右孩子 和 右节点的左孩子

C++代码:

/**
 * 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;
        }
    return symmetric(root->left,root->right);

    }
    bool symmetric(TreeNode* l,TreeNode* r){
        if(l == NULL && r== NULL){
        return true;
        }
        if(l == NULL || r == NULL || l->val != r -> val){
        return false;
        }
        return symmetric(l->left,r->right) && symmetric(l->right,r->left);

    }

};

时间复杂度:O(n)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值