【C/C++刷题集】二叉树算法题(一)

🫧个人主页: 小年糕是糕手

💫个人专栏:《数据结构(初阶)》** 《C/C++刷题集》 《C语言》**

🎨你不能左右天气,但你可以改变心情;你不能改变过去,但你可以决定未来!



目录

一、单值二叉树

思路:要判断单值二叉树,只需遍历整棵树,检查所有节点的值是否与根节点值完全相同即可

二、相同的树

思路:要判断两棵树是否相同,可通过递归遍历同时比较两棵树的节点

三、对称二叉树(题二的拓展学习)

思路:判断对称二叉树,需验证根节点的左子树与右子树是否呈镜像对称(结构对称且对应节点值相同)

四、另一棵树的子树

思路:要解决这个问题,需先判断root中是否存在某个节点的子树与subRoot完全相同(结构和节点值均一致),可通过递归分别检查root的各个子树是否与subRoot匹配。


一、单值二叉树

https://leetcode.cn/problems/univalued-binary-tree/description/

思路:要判断单值二叉树,只需遍历整棵树,检查所有节点的值是否与根节点值完全相同即可
cpp 复制代码
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */
bool isUnivalTree(struct TreeNode* root) {
    if (root == NULL) {
        return true;
    }
    // root非空,root根左右孩子结点的值进行比
    if (root->left != NULL && root->left->val != root->val) {
        return false;
    }
    if (root->right != NULL && root->right->val != root->val) {
        return false;
    }
    return isUnivalTree(root->left) && isUnivalTree(root->right);
}

我们根据答案来进一步分析:如果root == NULL就代表他没有左结点或者右结点所以不参与和单值的比较所以返回true,下面如果root的左 / 右结点不等于空且他的值和父亲结点的值不相同就直接返回false,然后我们采用递归来实现,下面给出图解帮助大家近一步去理解:

我们可以看到左边的例子就是因为这个函数的返回值是bool类型的且我们函数的递归用的是&&操作符(isUnivalTree(root->left) && isUnivalTree(root->right) ),所以只要有一个值返回false整个函数的返回值就会是false。

二、相同的树

https://leetcode.cn/problems/same-tree/description/

思路:要判断两棵树是否相同,可通过递归遍历同时比较两棵树的节点
  • 若两棵树的当前节点都为空,返回true;
  • 若其中一棵节点为空另一棵非空,或两节点值不同,返回false;
  • 否则递归比较左子树和右子树,只有左右子树都相同,两棵树才相同。
cpp 复制代码
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */
bool isSameTree(struct TreeNode* p, struct 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);
}

我们根据来进一步分析:这个题目主要就是将俩个结点分为三种情况去讨论:

我们根据这个图来分析,首先p和q结点均不为空,且都为1,所以三个if条件都不符合,直接开始执行递归,来看左结点,依旧不符合三个if条件,继续执行,下一步俩个都为空返回true,右边与其类似,他是bool类型的返回值且return中间的操作符是&&,所以需要全为true,不可以出现false

三、对称二叉树(题二的拓展学习)

https://leetcode.cn/problems/symmetric-tree/description/

思路:判断对称二叉树,需验证根节点的左子树与右子树是否呈镜像对称(结构对称且对应节点值相同)
cpp 复制代码
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */
//我们还是要判断是否是相同的树
//左右子树想同他才是对称的树
bool isSameTree(struct TreeNode* p, struct 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->right) && isSameTree(p->right, q->left);
}

bool isSymmetric(struct TreeNode* root) {
    return isSameTree(root->left,root->right);
}

我们根据答案来进一步分析:上一题我们是俩个树进行比较是否相同,这题是来判断一棵树是否轴对称:

我们结合这幅图和代码来分析:首先这个题目不用于上一题的是他是镜像对比,我们需要交叉对比,首先p和q是想同的值进入,所以不符合三种if情况,直接进入递归,p走到左结点2,q走到左结点2(我们只分析其中一组即红线的部分),依旧不符合三个if我们继续进行递归,p走到左结点3,q走到右结点3(这里还有一次分裂递归我们不讨论了),依旧不符合情况,我们继续递归,p走到左结点NULL,q走到右结点NULL,我们发现符合if的第一个情况,我们直接返回true,其他的路线与上述分析类似,图中红色部分代表的是isSameTree(p->left,q->rigth);蓝色部分是 isSameTree(p->right,q->left)

四、另一棵树的子树

https://leetcode.cn/problems/subtree-of-another-tree/description/

思路:要解决这个问题,需先判断root中是否存在某个节点的子树与subRoot完全相同(结构和节点值均一致),可通过递归分别检查root的各个子树是否与subRoot匹配。
cpp 复制代码
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */
typedef struct TreeNode TreeNode;
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);
}
bool isSubtree(struct TreeNode* root, struct TreeNode* subRoot) {
    if (root == NULL) {
        return false;
    }
    if (isSameTree(root, subRoot)) {
        return true;
    }
    return isSubtree(root->left, subRoot) || isSubtree(root->right, subRoot);
}

我们根据答案来进一步分析:这题其实和判断是否为相同二叉树有着很大的相同点:

我们根据这副图的例子来逐帧分析:首先我们传过去的root是4,subRoot是4,进入isSameTree函数中,我们在第三个if中停止了并且return了一个false,这时候isSubtree函数开始了递归,我们看左结点的情况(右结点在这题中相对简单我们不讨论了),root变为4,subRoot还是4,这时候再次进入isSameTree函数中,前面三个if均不符合情况,我们return isSameTree(p->left, q->left) || isSameTree(p->right, q->right),此时我们依旧先看左边的情况,依旧不符合三个if条件,我们继续递归,下一次左边就是root == NULL && subRoot == NULL,直接返回了true,其他类推最终返回了一个true,解决完毕

相关推荐
沫璃染墨2 分钟前
《从零入门Linux系统篇(五十八):线程篇·十一——线程安全与死锁详解:从可重入到多锁管理》
linux·服务器·开发语言·c++·驱动开发·安全·架构
我命由我123452 分钟前
Photoshop - 了解 Photoshop
学习·职场和发展·产品运营·求职招聘·职场发展·学习方法·photoshop
打码的老程是远篁4 分钟前
手把手教你玩转大模型——3. Transformer 的位置编码——模型怎么知道谁在前,谁在后?
人工智能·算法
嘎嘎风5 分钟前
MiniMind 学习笔记之 06 一张图、一百行:MiniMind 的骨架
算法·源码
郝学胜_神的一滴6 分钟前
C++ Templates 05:那些容易踩坑的技巧性基础知识
c++·visual studio
用户7341681035488 分钟前
只盯被动响应做状态监测?论“控制信号”在变工况故障诊断中的重要作用
算法
Ivanqhz11 分钟前
MQA、GQA、稀疏/滑动窗口注意力及混合范式
人工智能·算法·机器学习
罗湖老棍子19 分钟前
荒岛野人(信息学奥赛一本通- P1637)(洛谷-P2421)
算法·数论·枚举·裴蜀定理·扩展欧几里得·扩展中国剩余定理
我命由我1234521 分钟前
Photoshop - Photoshop 迁移预设,动作和设置
学习·职场和发展·产品运营·求职招聘·职场发展·产品经理·学习方法
朝朝辞暮i24 分钟前
C++ 第 40 章:ROS2 Publisher + Timer + Subscriber + Callback + Executor 完整闭环
开发语言·c++·算法·ros2