zoukankan      html  css  js  c++  java
  • 比较两棵二叉树是否相同/一棵二叉树是否是另一棵二叉树的子树/一棵二叉树是否是另一颗二叉树的子结构

    本文章讨论两个问题:

    ①如何判断两棵二叉树的结构是一样的、对应的每个结点都有着相同的值。--即判断两棵二叉树是一样的

    ②给定两棵二叉树,如何判断一棵二叉树是另一棵二叉树的子结构

    ③给定两棵二叉树,如何判断一棵二叉树是另一棵二叉树的子树

    注意,子结点与子树不同。如下图所示,2,3,4都是1的子结构但是只有4是1的子树。

     

    一、判断两个二叉树是否完全一致

    (1)由于先序序列和中序序列可以完全确定一颗二叉树,因此可以将两个二叉树的先序序列和中序序列求出来,然后比较二者是否一致。

    (2)递归,比较根结点是否一样;如果根结点一样,再继续比较根的左右孩子是否一样。

     1 public boolean sameTree2(BinaryNode<T> root1, BinaryNode<T> root2){
     2         //树的结构不一样
     3         if((root1 == null && root2 != null) || (root1 != null && root2 == null))
     4             return false;
     5         
     6         //两棵树最终递归到终点时
     7         if(root1 == null && root2 == null)
     8             return true;
     9         
    10         if(root1.element.compareTo(root2.element) != 0)
    11             return false;
    12         else
    13             return sameTree2(root1.left, root2.left) && sameTree2(root1.right, root2.right);
    14     }

    二、一棵二叉树是否是另一棵二叉树的子树

    错误解法:此时不可以用得到两棵树的先序(中序、后序)遍历序列1、2,然后利用KMP算法判断2是否是1的子序列。

    原因:因为一个序列不能唯一构建一棵二叉树,如下图所示,1的先序遍历序列为 ABDEC,2的先序遍历序列为BDE,但是2不是1的子树。、

    与判断是否是子结构类似,只是在isSubtree的递归出口有些差别。

    //判断以当前root1为根的树,和以root2为根的树,是否是相同的树
        public static boolean isSubtree(TreeNode root1,TreeNode root2) {
            if(root1==null&&root2!=null)
                return false;
            if(root1!=null&&root2==null)
                return false;
            if(root2==null&&root1==null)
                return true;
            if(root1.val==root2.val)
            {
                return isSubtree(root1.left,root2.left)&&isSubtree(root1.right,root2.right);
            }
            else
                return false;
        }

    三、一棵二叉树是否是另一颗二叉树的子结构

    错误解法:判断子结构问题同样不能用子序列的方式进行,如图所示。

    原因1: 是子结构,不一定是子序列。 树1先序遍历 ABDEC,树3先序遍历ABC,3是1的子结构,但是序列不是其子序列。

    原因2:是子序列,不一定是子结构。如问题二图所示。

     1 /**
     2 public class TreeNode {
     3     int val = 0;
     4     TreeNode left = null;
     5     TreeNode right = null;
     6 
     7     public TreeNode(int val) {
     8         this.val = val;
     9 
    10     }
    11 
    12 }
    13 */
    14 public class Solution {
    15     //判断以当前root1为根的树,和以root2为根的树,是否是根相同的子结构
    16     public static boolean isSubtree(TreeNode root1,TreeNode root2) {
    17         if(root1==null&&root2!=null)
    18             return false;
    19         if(root2==null)
    20             return true;
    21         if(root1.val==root2.val)
    22         {
    23             return isSubtree(root1.left,root2.left)&&isSubtree(root1.right,root2.right);
    24         }
    25         else
    26             return false;
    27     }
    28     
    29     //只用一个函数,由于需要递归,递归出口与判断初始树是否为空矛盾。
    30     //此函数当前节点不相等则继续比较左右子树,与上面的函数不同
    31     //将判断当前子树与目标子树是否相同作为一个单独的函数(isSubtree)。
    32     public static boolean HasSubtree(TreeNode root1,TreeNode root2) {
    33         if(root1==null&&root2!=null)
    34             return false;
    35         if(root2==null)
    36             return false;   //空树不是任一树的子结构
    37         boolean tag=false;
    38         tag=isSubtree(root1,root2);
    39         if(tag==true)
    40             return true;
    41         else{
    42             tag=HasSubtree(root1.left,root2);    //此处的函数调用为HasSubtree,因为isSubtree只判断当前根节点相同的子结构,不会递归判断子树
    43             if(tag==true)
    44                 return true;
    45             else
    46                 return HasSubtree(root1.right,root2);
    47         }
    48     }
    49 }

     另外拓展:三种遍历序列中,中序遍历+前序/后序即可重建二叉树。但是只有前序和后序遍历序列无法重建二叉树。

  • 相关阅读:
    揭开webRTC媒体服务器的神秘面纱——WebRTC媒体服务器&开源项目介绍
    打造一个上传图片到图床利器的插件(Mac版 开源)
    游戏编程十年总结(下)
    游戏编程十年总结(上)
    使用“Cocos引擎”创建的cpp工程如何在VS中调试Cocos2d-x源码
    手机网游实时同步方案
    Unity AssetBundle爬坑手记
    Unity3D新手引导开发手记
    敏捷开发随笔(一)高效软件开发之道
    U3D DrawCall优化手记
  • 原文地址:https://www.cnblogs.com/simpleDi/p/11430202.html
Copyright © 2011-2022 走看看