PAT-L2-004. 這是二叉搜尋樹嗎?(資料結構)
阿新 • • 發佈:2018-12-26
一棵二叉搜尋樹可被遞迴地定義為具有下列性質的二叉樹:對於任一結點,
- 其左子樹中所有結點的鍵值小於該結點的鍵值;
- 其右子樹中所有結點的鍵值大於等於該結點的鍵值;
- 其左右子樹都是二叉搜尋樹。
所謂二叉搜尋樹的“映象”,即將所有結點的左右子樹對換位置後所得到的樹。
給定一個整數鍵值序列,現請你編寫程式,判斷這是否是對一棵二叉搜尋樹或其映象進行前序遍歷的結果。
輸入格式:
輸入的第一行給出正整數N(<=1000)。隨後一行給出N個整數鍵值,其間以空格分隔。
輸出格式:
如果輸入序列是對一棵二叉搜尋樹或其映象進行前序遍歷的結果,則首先在一行中輸出“YES”,然後在下一行輸出該樹後序遍歷的結果。數字間有1個空格,一行的首尾不得有多餘空格。若答案是否,則輸出“NO”。
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
分析: 因為是判斷是否為二叉搜尋樹,所以可以利用它的特性,結點左邊的都比結點小,結點右邊的都不小於結點
然後給出的是先序遍歷(根左右) 所以要找哪些是左子樹,哪些是右子樹,只需要從前往後比較找出第一個大於結點的,從後往前找出第一個小於根結點的
(如果這兩個的距離大於1 說明不是二叉搜尋樹) 遞迴下去就可以了~
程式碼:
#include<bits/stdc++.h> using namespace std; vector<int>v; int value[2000]; void vjudge(int L,int R,int flag) { int l=L+1,r=R; if(L>R) return; if(!flag) { while(l<=R&&value[l]<value[L]) l++; while(r>L&&value[r]>=value[L]) r--; } else { while(l<=R&&value[l]>=value[L]) l++; while(r>L&&value[r]<value[L]) r--; } if(l-r!=1) return; vjudge(L+1,r,flag); vjudge(l,R,flag); v.push_back(value[L]); } int main() { int n; scanf("%d",&n); for(int i=0;i<n;i++) scanf("%d",&value[i]); vjudge(0,n-1,0); if(v.size()==0) { vjudge(0,n-1,1); } if(v.size()==n) { printf("YES\n"); for(int i=0;i<n;i++) printf("%d%c",v[i],i==n-1?'\n':' '); } else printf("NO\n"); }