0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看威廉希尔官方网站 视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

判断对称二叉树要比较的是哪两个节点

算法与数据结构 来源:代码随想录 作者:程序员Carl 2022-07-06 16:26 次阅读

101. 对称二叉树

给定一个二叉树,检查它是否是镜像对称的。

c54bc0e8-fd04-11ec-ba43-dac502259ad0.png

思路

首先想清楚,判断对称二叉树要比较的是哪两个节点,要比较的可不是左右节点!

对于二叉树是否对称,要比较的是根节点的左子树与右子树是不是相互翻转的,理解这一点就知道了其实我们要比较的是两个树(这两个树是根节点的左右子树),所以在递归遍历的过程中,也是要同时遍历两棵树。

那么如果比较呢?

比较的是两个子树的里侧和外侧的元素是否相等。如图所示:

c56013f4-fd04-11ec-ba43-dac502259ad0.png

那么遍历的顺序应该是什么样的呢?

本题遍历只能是“后序遍历”,因为我们要通过递归函数的返回值来判断两个子树的内侧节点和外侧节点是否相等。

正是因为要遍历两棵树而且要比较内侧和外侧节点,所以准确的来说是一个树的遍历顺序是左右中,一个树的遍历顺序是右左中。

但都可以理解算是后序遍历,尽管已经不是严格上在一个树上进行遍历的后序遍历了。

其实后序也可以理解为是一种回溯,当然这是题外话,讲回溯的时候会重点讲的。

说到这大家可能感觉我有点啰嗦,哪有这么多道理,上来就干就完事了。别急,我说的这些在下面的代码讲解中都有身影。

那么我们先来看看递归法的代码应该怎么写。

递归法

递归三部曲

确定递归函数的参数和返回值

因为我们要比较的是根节点的两个子树是否是相互翻转的,进而判断这个树是不是对称树,所以要比较的是两个树,参数自然也是左子树节点和右子树节点。

返回值自然是bool类型。

代码如下:

poYBAGLFR4yAPVqWAAAQuPTXo1A904.jpg

确定终止条件

要比较两个节点数值相不相同,首先要把两个节点为空的情况弄清楚!否则后面比较数值的时候就会操作空指针了。

节点为空的情况有:(注意我们比较的其实不是左孩子和右孩子,所以如下我称之为左节点右节点)

左节点为空,右节点不为空,不对称,return false

左不为空,右为空,不对称 return false

左右都为空,对称,返回true

此时已经排除掉了节点为空的情况,那么剩下的就是左右节点不为空:

左右都不为空,比较节点数值,不相同就return false

此时左右节点不为空,且数值也不相同的情况我们也处理了。

代码如下:

pYYBAGLFR6aAY2QmAABITjMqXUc205.jpg

注意上面最后一种情况,我没有使用else,而是elseif, 因为我们把以上情况都排除之后,剩下的就是 左右节点都不为空,且数值相同的情况。

确定单层递归的逻辑

此时才进入单层递归的逻辑,单层递归的逻辑就是处理 右节点都不为空,且数值相同的情况。

比较二叉树外侧是否对称:传入的是左节点的左孩子,右节点的右孩子。

比较内测是否对称,传入左节点的右孩子,右节点的左孩子。

如果左右都对称就返回true ,有一侧不对称就返回false 。

代码如下:

poYBAGLFR8GAek6NAABGcSkJYew381.jpg

如上代码中,我们可以看出使用的遍历方式,左子树左右中,右子树右左中,所以我把这个遍历顺序也称之为“后序遍历”(尽管不是严格的后序遍历)。

最后递归的C++整体代码如下:

poYBAGLFR9-AKoDSAADhGvnLjmI811.jpg

我给出的代码并不简洁,但是把每一步判断的逻辑都清楚的描绘出来了。

如果上来就看网上各种简洁的代码,看起来真的很简单,但是很多逻辑都掩盖掉了,而题解可能也没有把掩盖掉的逻辑说清楚。

盲目的照着抄,结果就是:发现这是一道“简单题”,稀里糊涂的就过了,但是真正的每一步判断逻辑未必想到清楚。

当然我可以把如上代码整理如下:

pYYBAGLFR_WAakX3AACMdaxuhp0814.jpg

这个代码就很简洁了,但隐藏了很多逻辑,条理不清晰,而且递归三部曲,在这里完全体现不出来。

所以建议大家做题的时候,一定要想清楚逻辑,每一步做什么。把道题目所有情况想到位,相应的代码写出来之后,再去追求简洁代码的效果。

迭代法

这道题目我们也可以使用迭代法,但要注意,这里的迭代法可不是前中后序的迭代写法,因为本题的本质是判断两个树是否是相互翻转的,其实已经不是所谓二叉树遍历的前中后序的关系了。

这里我们可以使用队列来比较两个树(根节点的左右子树)是否相互翻转,(注意这不是层序遍历)

使用队列

通过队列来判断根节点的左子树和右子树的内侧和外侧是否相等,如动画所示:

c575382e-fd04-11ec-ba43-dac502259ad0.gif

如下的条件判断和递归的逻辑是一样的。

代码如下:

poYBAGLFSBGAefZLAADwW9iQ3gw401.jpg

使用栈

细心的话,其实可以发现,这个迭代法,其实是把左右两个子树要比较的元素顺序放进一个容器,然后成对成对的取出来进行比较,那么其实使用栈也是可以的。

只要把队列原封不动的改成栈就可以了,我下面也给出了代码。

poYBAGLFSCiAYppNAACr8ADruEI559.jpg

总结

这次我们又深度剖析了一道二叉树的“简单题”,大家会发现,真正的把题目搞清楚其实并不简单,leetcode上accept了和真正掌握了还是有距离的。

我们介绍了递归法和迭代法,递归依然通过递归三部曲来解决了这道题目,如果只看精简的代码根本看不出来递归三部曲是如果解题的。

在迭代法中我们使用了队列,需要注意的是这不是层序遍历,而且仅仅通过一个容器来成对的存放我们要比较的元素,知道这一本质之后就发现,用队列,用栈,甚至用数组,都是可以的。

如果已经做过这道题目的同学,读完文章可以再去看看这道题目,思考一下,会有不一样的发现!

相关题目推荐

100.相同的树

572.另一个树的子树

其他语言版本

Java

pYYBAGLFSF2ADY9uAACr4DprcZA332.jpg

poYBAGLFSG6AKXUhAAEOFGGfMWU626.jpg

poYBAGLFSHaAackKAAD6VGhZVno319.jpg

Python

递归法:

poYBAGLFSIyASH4MAADTVj4n-so737.jpg

迭代法:使用队列

poYBAGLFSKCAcVZxAADvrTwwIis108.jpg

迭代法:使用栈

poYBAGLFSLaAWPsjAACc4bGIAhg462.jpg





审核编辑:刘清

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • JAVA
    +关注

    关注

    19

    文章

    2967

    浏览量

    104729
  • python
    +关注

    关注

    56

    文章

    4795

    浏览量

    84656

原文标题:判断二叉树是否对称

文章出处:【微信号:TheAlgorithm,微信公众号:算法与数据结构】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    什么是默克尔(Merkle Tree)?如何计算默克尔根?

    01 默克尔的概念 默克尔(Merkle Tree)是一种特殊的二叉树,它的每个节点都存储了一数据块的哈希值。哈希值是一种可以将任意长
    的头像 发表于 09-30 18:22 857次阅读
    什么是默克尔<b class='flag-5'>树</b>(Merkle Tree)?如何计算默克尔根?

    两个极管反向串联是什么元件

    两个极管反向串联是一种常见的电路元件,通常被称为双向极管或双向稳压极管。这种元件具有独特的电气特性,可以在正向和反向电压下工作,广泛应用于各种电子电路中。 一、双向
    的头像 发表于 08-16 16:05 3120次阅读

    极管的伏安特性分为两个部分?

    极管是一种半导体器件,具有单向导电性。其伏安特性是描述极管在不同电压下电流变化的曲线。极管的伏安特性可以分为两个部分:正向特性和反向特性。 正向特性 正向特性是指
    的头像 发表于 08-16 11:16 829次阅读

    触发器的两个稳定状态分别是什么

    触发器作为数字电路中的基本逻辑单元,具有两个稳定状态,这两个状态通常用于表示进制数码中的0和1。
    的头像 发表于 08-12 11:01 1097次阅读

    使用比较器TLV7041判断两个信号的大小,但输出未按预期进行是怎么回事?

    我现在需要使用比较判断两个信号的大小,但输出未按预期进行(不能比较者大小)。如下图,U17是比较
    发表于 08-12 08:20

    节点电压法流入节点电流怎么判断正负

    的电压。在分析过程中,我们需要判断流入节点的电流的正负。 节点电压法概述 在节点电压法中,我们首先选择一参考
    的头像 发表于 08-06 17:24 2116次阅读

    运放做比较两个输入相等怎么办

    比较器是运放的一种常见应用,主要用于比较两个模拟信号的大小。 当运放用作比较器时,其两个输入端分别为非反向输入端(+)和反向输入端(-)。
    的头像 发表于 07-10 10:34 1031次阅读

    交流元继电器有两个线圈

    交流元继电器是一种常见的电气元件,广泛应用于各种电气控制系统中。它主要由两个线圈组成,这两个线圈分别是线圈1和线圈2。下面我们将详细介绍这两个线圈的特点、工作原理以及在实际应用中的注
    的头像 发表于 06-29 09:43 670次阅读

    电磁继电器分为两个电路

    的控制。根据其结构和工作原理,电磁继电器可以分为两个电路:控制电路和工作电路。 一、控制电路 控制电路是电磁继电器的重要组成部分,它的作用是提供电磁铁所需的电流,使其产生磁场。控制电路主要由电源、控制开关和
    的头像 发表于 06-21 09:28 636次阅读

    请问Stlcr1v1传感器的温度是通过两个引脚传出来的?如何让温度通过uart两个串口传出来?

    我们想做不联电脑手机机的单纯的单片机串口通信,不知道我们传感器的温度是通过两个引脚传出来的,也不知道怎么样让温度通过uart两个串口传出来。我们还把上面原本的初始程序给覆盖。有没有大佬知道温度是通过哪个引脚传出来的?这个传感器
    发表于 06-03 08:53

    两个铜片可以形成原电池吗

    两个铜片本身不能形成原电池,因为原电池的工作原理依赖于两个不同电位的电极材料之间的氧化还原反应。
    的头像 发表于 05-21 16:23 948次阅读

    arcgis中如何关联两个属性表

    在ArcGIS中,关联两个属性表是一重要的操作,可以通过此操作将两个表中的数据关联起来,以便进行分析和查询。下面是详细介绍如何在ArcGIS中实现属性表的关联。 首先,我们需要明确两个
    的头像 发表于 02-25 11:01 4203次阅读

    对称短路有哪些 对称短路的形式有四种

    对称短路有哪些 对称短路的形式有四种  对称短路是指电路中的两个电路元件或导线之间有相同的电位差,从而形成电流的直接流动。
    的头像 发表于 02-18 10:17 2435次阅读

    Psoc4 4247LQI483如何判断产生的中断是由两个比较器中的哪一输出的上升沿触发的呢?

    LPcomparator的中断使能时,提示我们使用global signal reference并且选择LPCompInt。那么,我们如何判断这个产生的中断是由两个比较器中的哪一输出
    发表于 02-18 08:26

    ADuC824正弦波转方波时频带要比较宽时怎么办?

    低频时转换来的方波的波形单片机识别不了还是怎么的。有谁遇到过这种问题吗??有没有AD芯片低功耗频带快的比较器啊??我可以在比较器的输出端加两个对接的稳压管来时其输出的方波更好吗???
    发表于 01-15 06:42