求一个二叉树是否为另一个二叉树的子树

来源:互联网 发布:大数据的未来前景 编辑:程序博客网 时间:2024/04/26 11:15

**对于两棵彼此独立的二叉树A和B,请编写一个高效算法,检查A中是否存在一棵子树与B树的拓扑结构完全相同。
给定两棵二叉树的头结点A和B,请返回一个bool值,代表A中是否存在一棵同构于B的子树。**


直接把两个二叉树通过前序遍历形成字符串,在判断字符串A是否包含字符串B,主要用到的是KMP算法(http://blog.csdn.net/maotianwang/article/details/34466483)。

感觉表达有欠缺,不明白的地方可以点击上面的链接查看/*public class TreeNode {    int val = 0;    TreeNode left = null;    TreeNode right = null;    public TreeNode(int val) {        this.val = val;    }}*/public class IdenticalTree {     StringBuffer buffer=new StringBuffer();     StringBuffer buffer2=new StringBuffer();    public boolean chkIdentical(TreeNode A, TreeNode B) {//传进来两个二叉树A、B        String a=change(A);//递归,前序遍历二叉树,得到字符串        String b=change(B);        int i=getIndexOf(a,b);//判断a是否包括b        if(i==-1)            return false;        return true;    }        public int getIndexOf(String A,String B){            if(B.length()>A.length())                return -1;            int[] next=getIndex(B);            char[] a=A.toCharArray();            char[] b=B.toCharArray();            int i=0;int j=0;            while(j<b.length&&i<a.length){                if(a[i]==b[j]){//相等的话,AB字符串一起向前推进                    i++;                    j++;                }else if(next[j]==-1){//代表B仍然比较第一个字符,因为next[0]=-1                    i++;                }else{//如果B比较i+1不相等,这得到i的最大公共部分,将A继续和B第next[i]进行比较,相当于将A向前动                    //i-next[i]个,如ABCABE,ABCABD,第6个不一样,但前五个,公共部分长度为2,这将ABCABE中E和                    //ABCABD中C进行比较,相当于ABCABE向前推动i-next[i]个。                    j=next[j];                }            }            if(j==b.length)//如果长度一样,这代表匹配到最后一个,成功                return 0;            return -1;        }        public int[] getIndex(String a){            char[] b=a.toCharArray();            int[] next=new int[b.length+1];            next[0]=-1;            next[1]=0;            int cur=2;//从字符串第二个字符算起            int cn=0;            while(cur<next.length){                if(b[cur-1]==b[cn]){//因为next[1]是确定的,比较第2个和第next[1]字符,即第cur-1个和第next[cur-1]                    cn++;//如果一样,则公共部分长度+1,                    next[cur]=cn;                    cur++;                }else if(cn>0){//如果cn>0,代表之前有公共的部分,这将之前继续求公共部分,如                    //abacaba一样,前缀aba后缀aba,比较aba的前缀ab中b和abacaba下个字符,因aba=aba,所以a=a=a=a,则第一个和最后一个相等                    cn=next[cn];                }else{//若没有,则代表目前公共部分长度为0                    next[cur]=0;                    cur++;                }            }return next;        }        public String change(TreeNode tree){//递归,前左右,然后细分,将左边继续前左右分,右边,前左右分,累计            if(tree==null)        {            return "#";        }       StringBuilder sb=new StringBuilder();       sb.append(tree.val);       sb.append(change(tree.left));       sb.append(change(tree.right));       return sb.toString();        }}
0 0
原创粉丝点击