題意
一棵二叉搜尋樹可被遞迴地定義為具有下列性質的二叉樹:對於任一結點,其左子樹中所有結點的鍵值小於該結點的鍵值;其右子樹中所有結點的鍵值大於等於該結點的鍵值;其左右子樹都是二叉搜尋樹。所謂二叉搜尋樹的「映象」,即將所有結點的左右子樹對換位置後所得到的樹。給定乙個整數鍵值序列,現請你編寫程式,判斷這是否是對一棵二叉搜尋樹或其映象進行前序遍歷的結果。
輸入
輸入的第一行給出正整數 n(≤1000)。隨後一行給出 n 個整數鍵值,其間以空格分隔。
輸出
如果輸入序列是對一棵二叉搜尋樹或其映象進行前序遍歷的結果,則首先在一行中輸出yes
,然後在下一行輸出該樹後序遍歷的結果。數字間有 1 個空格,一行的首尾不得有多餘空格。若答案是否,則輸出no
。
樣例輸入
1)
7
8 6 5 7 10 8 11
2)
7
8 10 11 8 6 7 5
3)
7
8 6 8 5 10 9 11
樣例輸出
1)
yes
5 7 6 8 11 10 8
2)
yes
11 8 10 7 5 6 8
3)
no
分析
使用前序遍歷和中序遍歷構造樹,如果一顆樹是而二叉搜尋樹,則它的中序遍歷是非遞減的,如果一棵樹是二叉搜尋樹的映象樹,那麼它的中序遍歷是非遞增的,我們可以通過這個性質以及題目給出的前序遍歷求出樹的中序遍歷,先構造二叉搜尋樹,如果失敗的話再進行構造二叉搜尋樹的映象樹,如果還是失敗就輸出「no」,否則輸出「yes」和構造成的樹的中序遍歷。
一棵二叉搜尋樹可被遞迴地定義為具有下列性質的二叉樹:對於任一結點,其左子樹中所有結點的鍵值小於該結點的鍵值;其右子樹中所有結點的鍵值大於等於該結點的鍵值;其左右子樹都是二叉搜尋樹。那麼二叉搜尋樹的映象樹的可這樣定義:對於任一結點,其左子樹中所有結點的鍵值大於等於該結點的鍵值;其右子樹中所有結點的鍵值小於該結點的鍵值;其左右子樹都是二叉搜尋樹的映象樹。
由於題目給出的結點鍵值可能是一樣的,因此在構造二叉搜尋樹的映象樹時,必須按照從後往前的順序在中序遍歷陣列中找和根節點,這樣和根節點鍵值相同的重複結點就會稱為左子樹,這樣才符合二叉搜尋樹的映象樹,如果不這樣的話,樣例二不會通過。
c++程式
#include#includeusing namespace std;
const int n=1005;
//結點
struct node
};//後序遍歷
bool flag;
void post(node *x)
}int pre[n],in[n];//前序遍歷和中序遍歷結果
//是否能構造一棵二叉樹
bool legal;
//根據前序遍歷和中序遍歷構造二叉搜尋樹
// l,r表示pre的區間,a,b表示in的區間,dir表示從前往後找,還是從後往前找
node* build(int l,int r,int a,int b,bool dir)
return null;
}//銷毀樹
void destroy(node *x)
}int main()
//二叉搜尋樹的中序遍歷是非遞減的 ,利用前序遍歷和中序遍歷構造二叉樹
sort(in,in+n);
legal=true;
node *root=build(0,n-1,0,n-1,true);
//如果構造失敗,說明不是二叉搜尋樹,進一步判斷它是否為二叉樹進行鏡面操作後的樹
if(!legal)
if(legal)//構造二叉搜尋樹或二叉搜尋樹映象後的樹成功
else//失敗
printf("no\n");
destroy(root);
return 0;
}
L2 004 這是二叉搜尋樹嗎?
時間限制 400 ms 記憶體限制 65536 kb 長度限制 8000 b 判題程式 standard 作者 陳越 一棵二叉搜尋樹可被遞迴地定義為具有下列性質的二叉樹 對於任一結點,所謂二叉搜尋樹的 映象 即將所有結點的左右子樹對換位置後所得到的樹。給定乙個整數鍵值序列,現請你編寫程式,判斷這是否...
L2 004 這是二叉搜尋樹嗎?
一棵二叉搜尋樹可被遞迴地定義為具有下列性質的二叉樹 對於任一結點,其左子樹中所有結點的鍵值小於該結點的鍵值 其右子樹中所有結點的鍵值大於等於該結點的鍵值 其左右子樹都是二叉搜尋樹。所謂二叉搜尋樹的 映象 即將所有結點的左右子樹對換位置後所得到的樹。給定乙個整數鍵值序列,現請你編寫程式,判斷這是否是對...
L2 004 這是二叉搜尋樹嗎?
時間限制 400 ms 記憶體限制 65536 kb 長度限制 8000 b 判題程式 standard 作者 陳越 一棵二叉搜尋樹可被遞迴地定義為具有下列性質的二叉樹 對於任一結點,所謂二叉搜尋樹的 映象 即將所有結點的左右子樹對換位置後所得到的樹。給定乙個整數鍵值序列,現請你編寫程式,判斷這是否...