時間限制
400 ms
記憶體限制
65536 kb
**長度限制
8000 b
判題程式
standard
作者
陳越
一棵二叉搜尋樹可被遞迴地定義為具有下列性質的二叉樹:對於任一結點,
所謂二叉搜尋樹的「映象」,即將所有結點的左右子樹對換位置後所得到的樹。
給定乙個整數鍵值序列,現請你編寫程式,判斷這是否是對一棵二叉搜尋樹或其映象進行前序遍歷的結果。
輸入格式:
輸入的第一行給出正整數n(<=1000)。隨後一行給出n個整數鍵值,其間以空格分隔。
輸出格式:
如果輸入序列是對一棵二叉搜尋樹或其映象進行前序遍歷的結果,則首先在一行中輸出「yes」,然後在下一行輸出該樹後序遍歷的結果。數字間有1個空格,一行的首尾不得有多餘空格。若答案是否,則輸出「no」。
輸入樣例1:
7輸出樣例1:8 6 5 7 10 8 11
yes輸入樣例2:5 7 6 8 11 10 8
7輸出樣例2:8 10 11 8 6 7 5
yes輸入樣例3:11 8 10 7 5 6 8
7輸出樣例3:8 6 8 5 10 9 11
no
分析:假設它是二叉搜尋樹,一開始ismirror為false,根據二叉搜尋樹的性質將已知的前序轉換為後序,怎麼由前序遍歷轉換成後序遍歷呢轉換過程中,如果發現最後輸出的後序陣列長度不為n,那就設ismirror為true,然後清空後序陣列,
重新再轉換一次(根據鏡面二叉搜尋樹的性質),如果依舊轉換後陣列大小不等於n,就輸出no否則輸出yes
我們根據前序遍歷的特點,第乙個點作為根節點,後面的所有點可以分為兩部分,左子樹和右子樹,那麼除去第乙個根節點後
如果是二叉搜尋樹(左小右大)剩下的所有點中間一定可以找到乙個分界線使左邊的所有點比第乙個點(即根節點)小,右邊的大。如:前序遍歷序列 4
1 3 2
6 5 7第乙個為根然後兩個下標向中間找分界使得左邊小右邊大,我們發現最終可以分成黃色和綠色兩部分而下標指向 j i 一開始i從左往右走,j從右往左走,然後再將每段進行重複操作,遞迴,最後遞迴完成才返回根節點,保證相當於根節點最後被訪問,這樣就完成了後序遍歷的轉換,我們發現對於乙個二叉搜尋樹來說,每次進行分段i,j下標都會是如圖所示的情形,i-j=1,而如果不是乙個二叉搜尋樹,下標ij一定會提前停下,並返回,最終導致後序遍歷的點的個數會小於n,由此我麼根據最終得到的後序遍歷點的個數是否等於n來判斷是否是二叉搜尋樹。
code:
#include #include #include #include using namespace std;
bool ismirror;
vectorpre;
vectorpost;
void getpost(int root,int tail)
else
if(i - j != 1) return ;
getpost(root+1,j);//左
getpost(i,tail);//右
post.push_back(pre[root]);
}int main()
getpost(0,n-1);
if(post.size() != n)
if(post.size() == n)
}else
return 0;
}
L2 004 這是二叉搜尋樹嗎?
時間限制 400 ms 記憶體限制 65536 kb 長度限制 8000 b 判題程式 standard 作者 陳越 一棵二叉搜尋樹可被遞迴地定義為具有下列性質的二叉樹 對於任一結點,所謂二叉搜尋樹的 映象 即將所有結點的左右子樹對換位置後所得到的樹。給定乙個整數鍵值序列,現請你編寫程式,判斷這是否...
L2 004 這是二叉搜尋樹嗎?
一棵二叉搜尋樹可被遞迴地定義為具有下列性質的二叉樹 對於任一結點,其左子樹中所有結點的鍵值小於該結點的鍵值 其右子樹中所有結點的鍵值大於等於該結點的鍵值 其左右子樹都是二叉搜尋樹。所謂二叉搜尋樹的 映象 即將所有結點的左右子樹對換位置後所得到的樹。給定乙個整數鍵值序列,現請你編寫程式,判斷這是否是對...
L2 004 這是二叉搜尋樹嗎?
時間限制 400 ms 記憶體限制 65536 kb 長度限制 8000 b 判題程式 standard 作者 陳越 一棵二叉搜尋樹可被遞迴地定義為具有下列性質的二叉樹 對於任一結點,所謂二叉搜尋樹的 映象 即將所有結點的左右子樹對換位置後所得到的樹。給定乙個整數鍵值序列,現請你編寫程式,判斷這是否...