通俗易懂的方法帮你解决 剑指 Offer 28. 对称的二叉树

文章描述了一种判断二叉树是否对称的方法,通过递归比较根节点的左右子树是否镜像对称。在递归过程中,首先处理特殊值(空节点),然后确定递归条件,当节点为空或节点值不相等时返回false。最后,在节点值相等的情况下,递归比较左右子树的内外侧节点对称性。
摘要由CSDN通过智能技术生成

剑指 Offer 28. 对称的二叉树

请实现一个函数,用来判断一棵二叉树是不是对称的。如果一棵二叉树和它的镜像一样,那么它是对称的。

例如,二叉树 [1,2,2,3,4,4,3] 是对称的。

1

/ \

2 2

/ \ / \

3 4 4 3

但是下面这个 [1,2,2,null,3,null,3] 则不是镜像对称的:

1

/ \

2 2

\ \

3 3

解题思路

  • 头节点直接判断两个子节点值是否相等,不想等就代表不对称

  • 对于头节点的左右子节点比较的是两个子树的内侧和外侧的元素是否相等。如图所示:

实现逻辑

  • 特殊值处理:当传入的头节点为空,直接返回true,因为空树就是对称的。

  • 递归法:(递归三部曲)

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

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

booleancheckFun(TreeNoderootA, TreeNoderootB);

  1. 确定终止条件

传入的两个节点都为空,返回true,其中一个节点为空或者两个节点都不是空但是两个节点值不相等,返回true。

if(rootA==null&&rootB==null) returntrue;

if(rootB==null||rootA==null||rootA.val!=rootB.val) returnfalse;

  1. 确定单层递归的逻辑

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

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

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

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

returncheckFun(rootA.left, rootB.right) &&checkFun(rootA.right, rootB.left);
  1. 基于上面递归三部曲,代码就写完了。

classSolution {
    publicbooleanisSymmetric(TreeNoderoot) {
        if(root==null) returntrue;
        returncheckFun(root.left, root.right);
    }
    publicbooleancheckFun(TreeNoderootA, TreeNoderootB){
        if(rootA==null&&rootB==null) returntrue;
        if(rootB==null||rootA==null||rootA.val!=rootB.val) returnfalse;
        returncheckFun(rootA.left, rootB.right) &&checkFun(rootA.right, rootB.left);
    }
}

实现逻辑图:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我来解答你的问题。 首先,让我们来看看二叉树的遍历方式。二叉树的遍历方式有三种:前序遍历、中序遍历和后序遍历。 - 前序遍历:先访问根节点,再访问左子树,最后访问右子树。 - 中序遍历:先访问左子树,再访问根节点,最后访问右子树。 - 后序遍历:先访问左子树,再访问右子树,最后访问根节点。 而在XML解析中,我们可以将XML文件看作一棵树,它的每个节点都有自己的标签、属性和内容。因此,在解析XML文件时,我们也可以采用类似于二叉树的遍历方式来遍历XML树。 具体来说,我们可以使用tinyxml2库中的函数来遍历XML树。以下是一个简单的示例代码,演示如何遍历XML树中的所有节点: ``` #include "tinyxml2.h" #include <iostream> using namespace tinyxml2; void TraverseXML(XMLElement* element) { if (element == nullptr) { return; } // 访问当前节点 std::cout << "Node name: " << element->Name() << std::endl; // 访问当前节点的属性 const XMLAttribute* attribute = element->FirstAttribute(); while (attribute != nullptr) { std::cout << "Attribute name: " << attribute->Name() << ", value: " << attribute->Value() << std::endl; attribute = attribute->Next(); } // 访问当前节点的内容 std::cout << "Node value: " << element->GetText() << std::endl; // 遍历当前节点的子节点 XMLElement* child = element->FirstChildElement(); while (child != nullptr) { TraverseXML(child); child = child->NextSiblingElement(); } } int main() { XMLDocument doc; doc.LoadFile("example.xml"); XMLElement* root = doc.FirstChildElement(); TraverseXML(root); return 0; } ``` 这段代码中,我们首先定义了一个TraverseXML函数,用于遍历XML树中的所有节点。该函数的参数是一个XMLElement针,表示当前节点。在函数内部,我们首先访问了当前节点的标签、属性和内容,然后遍历了当前节点的所有子节点。 在主函数中,我们首先使用XMLDocument类的LoadFile函数来加载XML文件,然后获取XML树的根节点,并将其作为参数传递给TraverseXML函数,从而遍历整个XML树。 希望这个通俗易懂的讲解能够助你理解如何使用tinyxml2遍历所有节点。如果你还有其他问题,可以随时问我哦!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值