PTA L2-004 这是二叉搜索树吗?——根据前序序列判断是否为二叉搜索树

这个题有一个非常诡异的地方。在一般的根据树结构判断是否为二叉树的问题中,这种情况:
在这里插入图片描述
是一定要特别注意的,如果用普通的dfs判断左、右子树是否小于、大于根节点,会把这颗树误判为二叉搜索树。
然而,如果仅给出一棵树的前序序列,让你判断是否是二叉搜索树,这种情况判为正确也是没问题的。因为它的前序序列,43165,还可以表示为下图的树:
在这里插入图片描述
这颗树是二叉搜索树。如果一个序列可以认为是BST,也可以不是BST,那么它就是BST···pta上的这一题是这么ac的。
也因此 前序序列无法唯一表示一颗二叉树(后序序列也不行。)

下面是由前序序列判断是否为BST的算法:

方法 isBST(int root,int tail)递归判断一棵树的左子树是否都小于根节点,右子树是否都大于根节点。
参数中的root表示为当前树的根节点,tail表示为最后一个结点。
方法体中的i、j, 分别初始化为根节点的下一个结点、当前树的最后一个节点。经过操作后,如果当前树是二叉排序树,则i为右子树第一点,j为左子树最后一点。因此如果i!=j+1,则该树不是二叉排序树。
如果是的话,继续进行左右子树遍历。
具体见代码。

public class Main {
	static int DLR[]=new int[1010];
	static ArrayList<Integer> LRD=new ArrayList<Integer>();
	static boolean isBST(int root,int tail) {//root为当前树根节点下表,tail为当前树最后一个节点下标
		if(root>tail) {
			return true;
		}
		int i=root+1;
		int j=tail;
		while(i<=tail&&DLR[i]<DLR[root]) {
			i++;
		}
		while(j>root&&DLR[j]>=DLR[root]) {
			j--;
		}
		if(j+1!=i) {
			return false;
		}
		if(!isBST(root+1,j)) {
			return false;
		}
		if(!isBST(i,tail)) {
			return false;
		}
		LRD.add(DLR[root]);
		return true;
	}
	static boolean reBST(int root,int tail) {
		//基本同上一个方法
	}
	static PrintWriter out=new PrintWriter(System.out);
	static void print() {
		for(int i=0;i<LRD.size();i++) {
			if(i!=0) {
				out.print(" ");
			}
			out.print(LRD.get(i));
		}
		out.flush();
		out.close();
	}
	public static void main(String args[]) {
		InputReader sc=new InputReader(System.in);
		int N=sc.nextInt();
		for(int i=0;i<N;i++) {
			DLR[i]=sc.nextInt();
		}
		if(isBST(0, N-1)) {
			out.println("YES");
			print();
		}else {
			LRD.clear();//清空链表的操作一定不要忘了!!
			if(reBST(0, N-1)) {
				out.println("YES");
				print();
			}else {
				out.println("NO");
				out.flush();
				out.close();
			}
		}
	}
}
发布了73 篇原创文章 · 获赞 3 · 访问量 3497

猜你喜欢

转载自blog.csdn.net/qq_42021845/article/details/104080072