《剑指offer》23&24、树的子结构与镜像二叉树

二叉树基础

关于二叉树的问题,请参考二叉树的预备知识,以及剑指offer之前的两道二叉树的题目。
《剑指offer》预备知识-链表与二叉树
《剑指offer》06&07、二叉树的重构与下一个结点

树的子结构

offer23的问题是给出两棵树A和B,判断B是否A的子结构(我们约定空树不是任何一棵树的子结构)
涉及到树的结构问题,80%以上是递归。我们需要先把找子结构的思路写出来,然后再顺势写出递归。
1、首先要判断AB是否空树
2、然后要找到A的一个节点,使得它恰为B的根节点;这个节点就是递归的起点,我们暂时称之为起始节点
关于寻找这个节点,这里存在第一个递归,如果A的根节点不是B的根节点,那就递归遍历A的左右子树去寻找这个起始节点。
3、找到起始节点以后,用第二个递归遍历判断A的这棵子树是否和B完全一致:如果节点不同就返回上一层,重新寻找新的起始节点;如果节点相同,递归遍历A的左右子树继续判断。
这样一来题解就很明显了,通过两次递归,分别完成寻找起始节点判断树的结构是否相同两个工作。代码如下:

class TreeNode:
    def __init__(self, x):
        self.val = x
        self.left = None
        self.right = None
        
# offer23-solution
class Solution:
    def HasSubtree(self, pRoot1, pRoot2):
        result = False
        if pRoot1 and pRoot2:
            if pRoot1.val == pRoot2.val:
                result = self.SubtreeCore(pRoot1, pRoot2)  # 根节点相同,进入第二个递归
            if not result:
                result = self.HasSubtree(pRoot1.left, pRoot2)  # 左子树递归找相同的节点
            if not result:
                result = self.HasSubtree(pRoot1.right, pRoot2)  # 右子树递归找相同的节点
        return result

    def SubtreeCore(self, pRoot1, pRoot2):
        if pRoot1 == None or pRoot2 == None:  # A树或B树为空树
            return True
        elif pRoot1.val != pRoot2.val:  # 节点不同,不是子结构
            return False
        else:  # 对左右子树进行递归
            return self.SubtreeCore(pRoot1.left, pRoot2.left) 
               and self.SubtreeCore(pRoot1.right, pRoot2.right)

镜像二叉树

镜像二叉树实际就是要交换它的左右子树。那就用一次递归就好了……代码1给出的是原地修改生成镜像树,代码2给出的是生成一棵新的镜像二叉树,参考给出的是非递归的方法。

# offer24-solution1
# 其实not root.left and not root.right可以写得更为简洁,请各位自行思考,我在这里写冗余了
def Mirror1(self, root):
    if not root or not root.left and not root.right:
        return root
    root.left, root.right = root.right, root.left
    if root.left:
        self.Mirror1(root.left)
    if root.right:
        self.Mirror1(root.right)

# offer24-solution2
def Mirror2(self, root):
    if not root or not root.left and not root.right:
        return
    newTree = treeNode(root.val)
    if root.left:
        newTree.right = self.Mirror2(root.left)
    if root.right:  
        newTree.left = self.Mirror2(root.right)
    return newTree

非递归的方式,就要借助栈和队列了。
二叉树的镜像递归非递归求解

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值