L2-004. 這是二叉搜索樹嗎?
阿新 • • 發佈:2017-11-10
結果 emc col ostream 前序遍歷 格式 int 搜索樹 進行
輸入樣例1:
一棵二叉搜索樹可被遞歸地定義為具有下列性質的二叉樹:對於任一結點,
- 其左子樹中所有結點的鍵值小於該結點的鍵值;
- 其右子樹中所有結點的鍵值大於等於該結點的鍵值;
- 其左右子樹都是二叉搜索樹。
所謂二叉搜索樹的“鏡像”,即將所有結點的左右子樹對換位置後所得到的樹。
給定一個整數鍵值序列,現請你編寫程序,判斷這是否是對一棵二叉搜索樹或其鏡像進行前序遍歷的結果。
輸入格式:
輸入的第一行給出正整數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
根據給出的前序或鏡像前序,再根據二叉搜索樹的性質,可以得到後序遍歷,加入符合條件,後序遍歷數組大小應該為n,否則小於n。
代碼:
#include <iostream> #include <cstring> using namespacestd; int m[1000],num,post[1000]; void getpost(int l,int r,int flag)//尋找後序 l為根r為最右斷 flag代表不同的選擇 0 為前序,1為鏡像前序 { int ll = l + 1,rr = r; if(!flag)前序遍歷是按照 根 左子樹(鍵值全部小於根) 右子樹(鍵值全部大於等於根) 的順序排列的 { while(ll <= r && m[ll] < m[l])ll ++; while(l < rr && m[rr] >= m[l])rr --; }else //鏡像前序遍歷是按照 根 右子樹(鍵值全部大於等於根) 左子樹(鍵值全部小於根) 的順序排列的 { while(ll <= r && m[ll] >= m[l])ll ++; while(l < rr && m[rr] < m[l])rr --; } if(ll - rr == 1)//如果是正常的 ll肯定會多前進一個位置,rr會多前進一個位置 { getpost(l + 1,rr,flag);//左子樹 getpost(ll,r,flag);//右子樹 } else return; //不滿足就直接反回 post[num ++] = m[l];//放在最後 形成的才是後序遍歷 } int main() { int n; cin>>n; for(int i = 0;i < n;i ++) { cin>>m[i]; } getpost(0,n-1,0); if(num != n) { num = 0; getpost(0,n-1,1); } if(num != n)cout<<"NO"; else { cout<<"YES"<<endl; for(int i = 0;i < num;i ++) { if(i)cout<<‘ ‘<<post[i]; else cout<<post[i]; } } }
L2-004. 這是二叉搜索樹嗎?