判断两序列是否为同一二叉搜索树序列

Problem Description
判断两序列是否为同一二叉搜索树序列
 

 

Input
开始一个数n,(1<=n<=20) 表示有n个需要判断,n= 0 的时候输入结束。
接下去一行是一个序列,序列长度小于10,包含(0~9)的数字,没有重复数字,根据这个序列可以构造出一颗二叉搜索树。
接下去的n行有n个序列,每个序列格式跟第一个序列一样,请判断这两个序列是否能组成同一颗二叉搜索树。
 

 

Output
如果序列相同则输出YES,否则输出NO
 

 

Sample Input
2 567432 543267 576342 0
 

 

Sample Output
YES NO

只有前(后)序和中序都相同才能算同一棵树,

二叉排序树的中序遍历是一样的 都是所有元素的升序排列 所有判等只需校验先序遍历是否相等即可

 

二叉查找树

 

                 二叉查找树(Binary Search Tree),或者是一颗空树,或者是具有下列性质的二叉树:

                       1、若它的左子树不空,则其左子树上的所有结点的值均小于它根结点的值;

                       2、若它的右子树不空,则其右子树上的所有结点的值均大于它根结点的值;

                       3、它的左、右子树也分别为二叉查找树。

                                                  

                 二叉查找树是基于二叉树的,其结点数据结构定义为如下:

[java] view plaincopy
 
  1.   
  2. static class BinaryNode  
  3. {  
  4.     T data;  
  5.     BinaryNode left;  
  6.     BinaryNode right;  
  7.     public BinaryNode(T data) {  
  8.         this(data,null,null);  
  9.     }  
  10.     public BinaryNode( T data, BinaryNode left, BinaryNode right) {  
  11.         this.data =data;  
  12.         this.left = left;  
  13.         this.right =right;  
  14.     }  
  15.     public BinaryNode()  
  16.     {  
  17.         data =null;  
  18.         this.left = left;  
  19.         this.right =right;  
  20.     }  
  21. }  

 

查找操作

                       在二叉查找树中查找x的过程如下:

                             1、若二叉树是空树,则查找失败。

                             2、若x等于根结点的数据,则查找成功,否则。

                             3、若x小于根结点的数据,则递归查找其左子树,否则。

                             4、递归查找其右子树。

                     根据上述的步骤,写出其查找操作的代码: 

 

[java] view plaincopy
 
  1.   
  2.    public boolean contains(T t)  
  3.    {  
  4.       return contains(t, rootTree);  
  5.          
  6.    }  
  7.    
  8.    public boolean contains(T t, BinaryNode node)  
  9.    {  
  10.       if(node==null)  
  11.         return false;//结点为空,查找失败  
  12.       int result = t.compareTo(node.data);  
  13.        if(result>0)  
  14.           return contains(t,node.right);//递归查询右子树  
  15.       else if(result<</SPAN>0)  
  16.           return contains(t, node.left);//递归查询左子树    
  17.       else  
  18.           return true;  
  19.    }  

 插入操作

                     二叉树查找树b插入操作x的过程如下:

                        1、若b是空树,则直接将插入的结点作为根结点插入。

                        2、x等于b的根结点的数据的值,则直接返回,否则。

                        3、若x小于b的根结点的数据的值,则将x要插入的结点的位置改变为b的左子树,否则。

                        4、将x要出入的结点的位置改变为b的右子树。

               代码实现如下:

 

[java] view plaincopy
 
  1.   
  2.    public void insert(T t)  
  3.    {  
  4.        rootTree = insert(t, rootTree);  
  5.    }  
  6.   
  7.    public BinaryNode insert(T t,BinaryNode node)  
  8.    {  
  9.        if(node==null)  
  10.        {  
  11.            //新构造一个二叉查找树  
  12.            return new BinaryNode(t, nullnull);  
  13.        }  
  14.        int result = t.compareTo(node.data);  
  15.        if(result<</SPAN>0)  
  16.           node.left= insert(t,node.left);  
  17.        else if(result>0)  
  18.           node.right= insert(t,node.right);  
  19.        else  
  20.            ;//doNothing  
  21.        return node;  
  22.    }  

 

 

   删除操作

                         对于二叉查找树的删除操作(这里根据值删除,而非结点)分三种情况:

                   不过在此之前,我们应该确保根据给定的值找到了要删除的结点,如若没找到该结点

                   不会执行删除操作!

                      下面三种情况假设已经找到了要删除的结点。

                        1、如果结点为叶子结点(没有左、右子树),此时删除该结点不会玻化树的结构

                             直接删除即可,并修改其父结点指向它的引用为null.如下图:

                

                       2、如果其结点只包含左子树,或者右子树的话,此时直接删除该结点,并将其左子树

                              或者右子树设置为其父结点的左子树或者右子树即可,此操作不会破坏树结构。
                 
                           

                       3、 当结点的左右子树都不空的时候,一般的删除策略是用其右子树的最小数据

                            (容易找到)代替要删除的结点数据并递归删除该结点(此时为null),因为

                              右子树的最小结点不可能有左孩子,所以第二次删除较为容易。

                               z的左子树和右子树均不空。找到z的后继y,因为y一定没有左子树,所以可以删除y,

                              并让y的父亲节点成为y的右子树的父亲节点,并用y的值代替z的值.如图:

                    

                  删除操作源码:

 

[java] view plaincopy
 
  1.   
  2.    public void remove(T t)  
  3.    {  
  4.        rootTree = remove(t,rootTree);  
  5.    }   
  6.    public BinaryNode remove(T t,BinaryNode node)  
  7.    {  
  8.        if(node == null)  
  9.            return node;//没有找到,doNothing  
  10.        int result = t.compareTo(node.data);  
  11.        if(result>0)  
  12.            node.right = remove(t,node.right);  
  13.        else if(result<</SPAN>0)  
  14.            node.left = remove(t,node.left);  
  15.        else if(node.left!=null&&node.right!=null)  
  16.        {  
  17.            node.data = findMin(node.right).data;  
  18.            node.right = remove(node.data,node.right);  
  19.        }  
  20.        else  
  21.            node = (node.left!=null)?node.left:node.right;  
  22.        return node;  
  23.              
  24.    }  

二叉树的先序、中序、后序和层次遍历

 

  1. //先序遍历  
  2.     public void preTraverse(TreeNode root)  
  3.     {  
  4.         if(root!=null)  
  5.         {  
  6.             System.out.print(root.getData()+" ");  
  7.             preTraverse(root.getLchild());  
  8.             preTraverse(root.getRchild());  
  9.         }  
  10.     }  
  11.     //中序遍历  
  12.     public void midTraverse(TreeNode root)  
  13.     {  
  14.         if(root!=null)  
  15.         {  
  16.             midTraverse(root.getLchild());  
  17.             System.out.print(root.getData()+" ");  
  18.             midTraverse(root.getRchild());  
  19.         }  
  20.     }  
  21.     //后序遍历  
  22.     public void postTraverse(TreeNode root)  
  23.     {  
  24.         if(root!=null)  
  25.         {  
  26.             postTraverse(root.getLchild());  
  27.             postTraverse(root.getRchild());  
  28.             System.out.print(root.getData()+" ");  
  29.         }  
  30.     }  
  31.     //层次遍历  
  32.     public void levelTraverse(TreeNode root)  
  33.     {  
  34.         System.out.print(root.getData()+" ");  
  35.         queue.enQueue(root);  
  36.         int level=1;  
  37.         while(!queue.isEmpty())  
  38.         {  
  39.             List<TreeNode> list=new ArrayList<TreeNode>();  
  40.             while(!queue.isEmpty())  
  41.             {  
  42.                 list.add(queue.deQueue());  
  43.             }  
  44.             boolean tag=false;  
  45.             for(int i=0;i<list.size();i++)  
  46.             {  
  47.                if(list.get(i).getLchild()!=null)  
  48.                {  
  49.                 System.out.print(list.get(i).getLchild().getData()+" ");  
  50.                 queue.enQueue(list.get(i).getLchild());  
  51.                 tag=true;  
  52.                }  
  53.                if(list.get(i).getRchild()!=null)  
  54.                {  
  55.                 System.out.print(list.get(i).getRchild().getData()+" ");  
  56.                 queue.enQueue(list.get(i).getRchild());  
  57.                 tag=true;  
  58.                }  
  59.             }  
  60.             if(tag)  
  61.             {  
  62.                 level++;  
  63.             }  
  64.         }  
  65.         System.out.println("二叉树共"+level+"层");  
  66.     }  

 

 

此题正确代码如下:

import java.util.Scanner;

public class BinarySearch {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
Scanner sin=new Scanner(System.in);
int n=Integer.parseInt(sin.nextLine());
String s=sin.nextLine();
TreeNode t=buildTree(s);
String a=preVisit(t);
int count=0;
while(count<n){
	String ss=sin.nextLine();
	count++;
	TreeNode t2=buildTree(ss);          //这个地方一定记得用t2把返回值接住,否则值没有返回,后面会有空指针异常
	String b=preVisit(t2);
	//System.out.println(b);
	if(a.equals(b))
		System.out.println("YES");
	else System.out.println("NO");
}

	}
private static String preVisit(TreeNode t) {
		StringBuilder sb=new StringBuilder();
		if(t==null)
			return null;
		else{
			sb.append(t.data);
			sb.append(preVisit(t.left));               //和前面一样,一定要把结果加入sb,利用sb.append,否则直接写preVisit(t.left)的话,
			                                                                   //结果没有加入sb,只有根节点加入sb了,不对!
			sb.append(preVisit(t.right));
		}
		return sb.toString();
	}
private static TreeNode buildTree(String s) {
		TreeNode t=null;
		for(int i=0;i<s.length();i++){
			t=insert(t,s.charAt(i)-'0');
		}
		return t;
	}

public static TreeNode insert(TreeNode t,int data){
	if(t==null)
		return new TreeNode(data);
   if(data<t.data)
	   t.left=insert(t.left, data);               
   else if(data>t.data)
	   t.right=insert(t.right,data);
   else 
	   ;
   return t;
	   
}
}


class TreeNode{
	int data;
	TreeNode left;
	TreeNode right;
	public TreeNode(int data){
		this.data=data;
	}
}



 

posted @ 2015-07-05 10:51  berylqliu  阅读(2094)  评论(0编辑  收藏  举报