PTA L2-004 這是二叉搜索樹嗎?(C++)

一棵二叉搜索樹可被遞歸地定義爲具有下列性質的二叉樹:對於任一結點,

其左子樹中所有結點的鍵值小於該結點的鍵值;
其右子樹中所有結點的鍵值大於等於該結點的鍵值;
其左右子樹都是二叉搜索樹。
所謂二叉搜索樹的“鏡像”,即將所有結點的左右子樹對換位置後所得到的樹。

給定一個整數鍵值序列,現請你編寫程序,判斷這是否是對一棵二叉搜索樹或其鏡像進行前序遍歷的結果。

輸入格式:
輸入的第一行給出正整數 N(≤1000)。隨後一行給出 N 個整數鍵值,其間以空格分隔。

輸出格式:
如果輸入序列是對一棵二叉搜索樹或其鏡像進行前序遍歷的結果,則首先在一行中輸出 YES ,然後在下一行輸出該樹後序遍歷的結果。數字間有 1 個空格,一行的首尾不得有多餘空格。若答案是否,則輸出 NO。

輸入樣例 1:
7
8 6 5 7 10 8 11
輸出樣例 1:
YES
5 7 6 8 11 10 8
輸入樣例 2:
7
8 10 11 8 6 7 5
輸出樣例 2:
YES
11 8 10 7 5 6 8
輸入樣例 3:
7
8 6 8 5 10 9 11
輸出樣例 3:
NO
—> 參考博客地址
前序遍歷:根結點 —> 左子樹 —> 右子樹
中序遍歷:左子樹—> 根結點 —> 右子樹
後序遍歷:左子樹 —> 右子樹 —> 根結點

分析:假設它是二叉搜索樹,一開始flag爲false,根據二叉搜索樹的性質將已知的前序轉換爲後序,轉換過程中,如果發現最後輸出的後序數組長度不爲n,那就設flag爲true(因爲還有可能是鏡面二叉搜索樹),然後清空後序數組,重新再轉換一次(根據鏡面二叉搜索樹的性質),如果依舊轉換後數組大小不等於n,就輸出NO否則輸出YES

#include <bits/stdc++.h>
using namespace std;
int n,arr[1010];
bool flag = false;
vector<int> res;
void helper(int down,int tail){
	if(down > tail) return;
	int left = down+1;
	int right = tail;
	if(!flag){
		while(left <= tail && arr[left] < arr[down]) left++;
		while(right > down && arr[right] >= arr[down]) right--;
	}
	else{
		while(left <= tail && arr[left] >= arr[down]) left++;
		while(right > down && arr[right] < arr[down]) right--;
	}
	if(left - right != 1) return ;		
	helper(down+1,right);	
	helper(left,tail);	
	res.push_back(arr[down]);	
}
int main(){
	cin>>n;
	for(int i = 0;i < n;i++){
		cin>>arr[i];
	}
	helper(0,n-1);
	if(res.size() != n){
		res.clear();
		flag = true;
		helper(0,n-1);
	}	
	if(res.size() == n){
		cout<<"YES"<<endl;
		cout<<res[0];	
		for(int i = 1;i < res.size();i++){
			cout<<" "<<res[i];
		}			
	}else{
		cout<<"NO";
	}
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章