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();
			}
		}
	}
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章