树的子结构

题:输入两棵二叉树A,B,判断B是不是A的子结构。(ps:我们约定空树不是任意一个树的子结构)

思路:首先要判定B是不是A的子结构。则需要判断B的根节点是否存在于A里面。这个很好写,直接递归遍历树A找出节点值等于B的根节点值的节点即可。

找到之后需要匹配B和从A中找出的这个节点是否一样,如果不一样,再从当前节点的左右子树一直找,找到后再匹配。一直重复查找-匹配这两步直到匹配成功或者遍历完A树为止。

怎么匹配呢。当然也是递归。依次匹配找到的节点和树B的左右子树,在遍历到树B的叶子节点之前,如果有节点的值不匹配,直接返回false。

代码:

/**
public class TreeNode {
    int val = 0;
    TreeNode left = null;
    TreeNode right = null;

    public TreeNode(int val) {
        this.val = val;

    }

}
*/
public class Solution {
    public boolean HasSubtree(TreeNode root1,TreeNode root2) {
        if(root1 == null || root2 == null)
            return false;

        TreeNode node = findNode(root1, root2);

        while (node != null){
            // 如果匹配成功,结束查找
            if(equalsNode(node, root2))
                return true;
            else {
                // 匹配不成功,继续查找
                TreeNode n = findNode(node.left, root2);
                // 再匹配
                if(equalsNode(n, root2))
                    return true;

                // 匹配不成功,再查找
                node = findNode(node.right, root2);
            }
        }

        return false;
    }

    public TreeNode findNode(TreeNode node1, TreeNode node2){
        if(node1 == null || node2 == null)
            return null;

        TreeNode node;
        // 查找成功
        if(node1.val == node2.val) {
            return node1;
        }else {
            // 查找不成功,从左子树开始继续查找
            node = findNode(node1.left, node2);
            if(node != null)
                return node;

            // 左子树没找到,再从右子树开始查找
            node = findNode(node1.right, node2);
        }

        return node;
    }

    public boolean equalsNode(TreeNode node1, TreeNode node2){
        // 如果B树已经到叶子节点,说明匹配成功
        if(node2 == null)
            return true;
        // 如果A数已经到叶子节点,说明匹配失败
        if(node1 == null)
            return false;

        if(node1.val != node2.val)
            return false;

        // 继续匹配树的下一层左右子树
        return equalsNode(node1.left, node2.left) && equalsNode(node1.right, node2.right);
    }
}

呕心沥血写出来的,转载请一定注明出处!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值