IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> JZ26 树的子结构 -> 正文阅读

[数据结构与算法]JZ26 树的子结构

描述

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

假如给定A为{8,8,7,9,2,#,#,#,#,4,7},B为{8,9,2},2个树的结构如下,可以看出B是A的子结构

数据范围:

0 <= A的节点个数 <= 10000

0 <= B的节点个数 <= 10000

示例1

输入:

{8,8,7,9,2,#,#,#,#,4,7},{8,9,2}

返回值:

true

示例2

输入:

{1,2,3,4,5},{2,4}

返回值:

true

示例3

输入:

{1,2,3},{3,1}

返回值:
false
好难,之前可能没遇到过 第一次做 完全不会

看了解析之后,发现难,难点在于:有两次递归
第一次递归仅仅只是遍历树1的结点而已
    找到与 树2根相同的节点时: 再单独将这两个节点作为根,再一起同步遍历判断是否一致

看完解析后,自己敲的代码:

递归代码:

   public boolean HasSubtree(TreeNode root1,TreeNode root2) {//只是遍历找匹配的根节点而已
        if(root2==null) return false;//空树不是任意一个树的子结构
        if(root1==null) return false;//这颗子树肯定没有 返回false
        if(root1.val==root2.val) {
            //找到与树2根相同得节点了 "摘下"以root1为根的子树开始同步遍历
            boolean f0=judge(root1,root2);
            if(f0) return true;//找到了直接返回 不递归了
        }

        boolean f1=HasSubtree(root1.left,root2);//大体结构 先序遍历root1 找与root2根相同的节点
        boolean f2=HasSubtree(root1.right,root2);//大体结构 先序遍历root1 找与root2根相同的节点  别忘记改成right

        return f1||f2;//左子树或者右子树找到匹配的均可
    }

    //真正核心 同步遍历了
    private boolean judge(TreeNode root1, TreeNode root2) {//此处初始root1 root2一定均不为null
        if(root2==null) return true;//root2遍历到null了  root1可以多点没事,正常结尾 这个分支不需要走了
        if(root1==null) return false;//此处root2肯定不为null root1却没了 必然不行
        if(root1.val!=root2.val){
            return false;//严格同步遍历到的值不等 肯定不行
        }
        //否则就是相等了 继续严格同步遍历下去即可
        boolean f1=judge(root1.left,root2.left);//完全严格同步地先序遍历了
        boolean f2=judge(root1.right,root2.right);//完全严格同步地先序遍历了

        return f1&&f2;//左右子树都重来没有返回false才行
    }

递归代码2:只是写好后再单纯地在语法层面进行了简化而已 (看起来又好厉害的亚子)

    public boolean HasSubtree(TreeNode root1,TreeNode root2) {//只是遍历找匹配的根节点而已
        if(root2==null||root1==null) return false;//空树不是任意一个树的子结构
        if(root1.val==root2.val && judge(root1,root2))  return true;
        return HasSubtree(root1.left,root2)||HasSubtree(root1.right,root2);//左子树或者右子树找到匹配的均可
    }
    //真正核心 同步遍历了
    private boolean judge(TreeNode root1, TreeNode root2) {//此处初始root1 root2一定均不为null
        if(root2==null) return true;//root2遍历到null了  root1可以多点没事,正常结尾 这个分支不需要走了  正常结尾返回true
        if(root1==null||root1.val!=root2.val) return false;//此处root2肯定不为null root1却没了 必然不行
        return judge(root1.left,root2.left)&&judge(root1.right,root2.right);//左右子树都重来没有返回false才行
    }

方法二:非递归解法 (代码长一点,但是没有递归,确实好理解一点了)

两次层序遍历
    第一次,寻找根节点相同的子树
    第二次:两树同步层次遍历: 此处其实很简单,以树2为基准判断是否将子节点add进队,树1完全相同操作且一直全部匹配即可


    java队列:
        add() 和 offer() 方法;二者都是向队列中添加元素
        当队列容量超过限制时,add()会报异常,offer()会返回false
   public boolean HasSubtree(TreeNode root1,TreeNode root2) {//只是遍历找匹配的根节点而已
        if(root2==null||root1==null) return false;
        Queue<TreeNode> q=new LinkedList<>();
        q.add(root1);
        while (!q.isEmpty()){//层序遍历 找与根相同的节点
            TreeNode p = q.poll();
            if(p.val==root2.val){
                if(judge(p,root2)){//看是否完全匹配  千万注意是 p和root2比较 p不要写成了root1
                    return true;
                }
            }
            if(p.left!=null) q.add(p.left);
            if(p.right!=null) q.add(p.right);
        }
        return false;//前面找到了匹配一定已经返回true了

    }
    //真正核心 同步遍历了
    private boolean judge(TreeNode root1, TreeNode root2) {//此处初始root1 root2一定均不为null
        Queue<TreeNode> q1=new LinkedList<>();
        Queue<TreeNode> q2=new LinkedList<>();
        q1.add(root1);q2.add(root2);
        while (!q2.isEmpty()){//以root2为基准 层序遍历root2 root1紧跟一样遍历 能完全匹配上就行
            TreeNode p1 = q1.poll();
            TreeNode p2 = q2.poll();
            if(p1==null) return false;//p2一定不为null p1却没了
            if(p1.val!=p2.val) return false;
            //接下来就是已经匹配了 得继续匹配其他节点了
            if(p2.left!=null){
                q1.add(p1.left);
                q2.add(p2.left);
            }
            if(p2.right!=null){
                q1.add(p1.right);
                q2.add(p2.right);
            }
        }
        return true;//中途没有返回false 说明完全匹配 返回true
    }

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-05-07 11:22:23  更:2022-05-07 11:22:58 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 3:31:59-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码