2021天梯賽模擬L2-3這是二叉搜尋樹嗎?
阿新 • • 發佈:2022-04-21
一棵二叉搜尋樹可被遞迴地定義為具有下列性質的二叉樹:對於任一結點,
其左子樹中所有結點的鍵值小於該結點的鍵值;
其右子樹中所有結點的鍵值大於等於該結點的鍵值;
其左右子樹都是二叉搜尋樹。
所謂二叉搜尋樹的“映象”,即將所有結點的左右子樹對換位置後所得到的樹。
給定一個整數鍵值序列,現請你編寫程式,判斷這是否是對一棵二叉搜尋樹或其映象進行前序遍歷的結果。
輸入格式:
輸入的第一行給出正整數 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
這道題的思路就是用遞迴的思想來進行後序遍歷輸出,先找左子樹,再找右子樹
#include<bits/stdc++.h> using namespace std; typedef long long ll; int n,pre[1010]; vector<int> post; bool mirror=false; void getpost(int root,int tail) { if(root>tail) return ; int i=root+1; int j=tail; int root_data=pre[root]; if(!mirror) { while(pre[i]<root_data&&i<=tail) i++; while(pre[j]>=root_data&&j>root) j--; } else//如果是映象,只要相反一下就行 { while(pre[i]>=root_data&&i<=tail) i++; while(pre[j]<root_data&&j>root) j--; } if(i!=j+1) return ; getpost(root+1,j);//找左子樹 getpost(i,tail);//找右子樹 post.push_back(root_data); //cout<<root_data<<endl; } int main() { cin>>n; for(int i=0;i<n;i++) { cin>>pre[i]; } getpost(0,n-1); if(post.size()<n)//vector小於n說明可能是映象,也可能都不是,後面再判斷一次 { post.clear(); mirror=true; getpost(0,n-1); } if(post.size()<n) cout<<"NO";//既不是二叉搜尋樹,也不是映象 else { cout<<"YES"<<endl; cout<<post[0]; for(int i=1;i<n;i++) { cout<<" "<<post[i]; } } return 0; }