性質
對二叉查找樹進行中序遍歷,遍歷的結果是有序的。
題目1:Is It a Binary Search Tree
https://pintia.cn/problem-sets/994805342720868352/problems/994805440976633856
自己寫的(多點的,建兩棵樹)
省題
輸入先序數組,按照先序數組建BST樹/BST鏡像樹。
若該數組確實是BST樹/BST鏡像樹的先序數組,那麼輸出YES,再輸出相對應(BST樹/BST鏡像樹)樹的後序數組
- 這裏BST的定義標準
a)The left subtree of a node contains only nodes with keys less than the node’s key.
b)The right subtree of a node contains only nodes with keys greater than or equal to the node’s key.
c)Both the left and right subtrees must also be binary search trees
小於根節點的在左子樹沒變;但是右子樹的性質變爲了大於等於根節點 - 鏡像BST樹的定義
If we swap the left and right subtrees of every node, then the resulting tree is called the Mirror Image of a BST.
如果我們交換每個節點的左右子樹,那麼得到的樹就稱爲BST的鏡像。
.
思路
設bool flag=false,若有 爲BST/鏡像BST的先序數組 其中一條滿足則爲true
根據先序數組建樹,若爲BST的先序數組,flag=true
若flag=false,再根據先序數組建鏡像樹,若爲鏡像BST的先序數組,flag=true
若flag=true則YES,按後序遍歷輸出,否則NO
根據鏡像BST的定義可知,鏡像BST左右孩子的定義與BST正相反,即
大於等於根節點的在左子樹;小於根節點的在右子樹
按照建樹的函數及其過程如法炮製建鏡像樹的函數及其過程
AC代碼
//根據先序建BST(第一個元素爲根),判斷該BST的先序是否爲輸入的先序
//如果是的,就輸出後序
#include<bits/stdc++.h>
using namespace std;
const int maxv=1010;
struct node{
int data;
node* lchild;
node* rchild;
};
int n,pre[maxv],step;
//新建結點
node* newnode(int x)
{
node* root=new node;
root->data=x;
root->lchild=root->rchild=NULL;
return root;
}
//插入
void insert(node* &root,int x)
{
if(root==NULL){
root=newnode(x);
return;
}
//省題
/*The left subtree of a node contains only nodes with keys less than the node's key.
The right subtree of a node contains only nodes with keys greater than or equal to the node's key.*/
else if(x<root->data)//小於根節點,在其左子樹
insert(root->lchild,x);
else if(x>=root->data)
insert(root->rchild,x);
}
//鏡像插入
void Minsert(node* &root,int x)
{
if(root==NULL){
root=newnode(x);
return;
}
//省題
/*If we swap the left and right subtrees of every node, then the resulting tree is called the Mirror Image of a BST.*/
else if(x>=root->data)//大於等於根節點,在其左子樹(和原來的相反)
Minsert(root->lchild,x);
else if(x<root->data)
Minsert(root->rchild,x);
}
//建樹
node* create()
{
node* root=NULL;
for(int i=1;i<=n;i++)
insert(root,pre[i]);
return root;
}
//鏡像建樹
node* Mcreate()
{
node* root=NULL;
for(int i=1;i<=n;i++)
Minsert(root,pre[i]);
return root;
}
bool preDFS(int &step,node* root)
{
if(pre[step]!=root->data)
return false;
if(root->lchild!=NULL)
if(!preDFS(++step,root->lchild))
return false;
if(root->rchild!=NULL)
if(!preDFS(++step,root->rchild))
return false;
return true;
}
void postDFS(node* root,node *R)
{
if(root->lchild!=NULL)
postDFS(root->lchild,R);
if(root->rchild!=NULL)
postDFS(root->rchild,R);
printf("%d%s",root->data,root==R?"\n":" ");
}
int main(){
while(scanf("%d",&n)!=EOF){
bool flag=false;
for(int i=1;i<=n;i++)
scanf("%d",&pre[i]);
node* root=create();
step=1;
if(preDFS(step,root))
flag=true;
if(!flag){
step=1;
root=Mcreate();
if(preDFS(step,root))
flag=true;
}
if(flag){
printf("YES\n");
postDFS(root,root);
}
else
printf("NO\n");
}
return 0;
}
小藍書上的(單點的,根據BST寫兩種的先序序列)
不同於我自己寫的:建兩棵樹分別判斷
小藍書上寫的是:建一棵樹,根據這棵樹遍歷出BST/鏡像BST的先序序列
根據BST遍歷出鏡像BST的先序序列就是把左右根的遍歷順序交換爲右左根,來滿足鏡像BST和BST的左右孩子相反的定義
AC代碼
#include<bits/stdc++.h>
using namespace std;
struct node {
int data; //數據域
node *left,*right; //指針域
} ;
void insert(node* &root, int data) {
if (root == NULL) {//到達空結點時, 即爲需要插入的位置
root = new node;
root->data = data;
root->left = root->right = NULL;//此句不能漏
return;
}
if (data < root->data)//插在左子樹
insert (root->left, data);
else//插在右子樹
insert(root->right, data);
}
//先序遍歷, 結果存在vi
void preOrder(node* root, vector<int>&vi) {
if(root == NULL)
return;
vi.push_back(root->data);
preOrder(root->left,vi);
preOrder(root->right,vi);
}
//鏡像樹先序遍歷, 結果存放於vi
void preOrderMirror(node* root, vector<int>&vi) {
if(root == NULL)
return;
vi.push_back(root->data);
preOrderMirror(root->right, vi);
preOrderMirror(root->left, vi);
}
//後序遍歷, 結果存放於vi
void postOrder(node* root,vector<int>&vi) {
if(root == NULL)
return;
postOrder(root->left, vi);
postOrder(root->right, vi);
vi.push_back(root->data);
}
//鏡像樹後序遍歷, 結果存放於vi
void postOrderMirror(node* root, vector<int>&vi) {
if(root == NULL)
return;
postOrderMirror(root->right, vi);
postOrderMirror(root->left, vi);
vi.push_back(root->data);
}
//origin 存放初始序列
//pre、post 爲先序、後序, preM、postM 爲鏡像樹先序、後序
vector<int> origin, pre, preM, post, postM;
int main() {
int n, data;
node* root=NULL;//定義頭結點
scanf ("%d", &n);//輸入結點個數
for(int i = 0; i < n; i++) {
scanf("%d", &data);
origin.push_back(data);//將數據加入origin
insert(root, data);//將data 插入二叉樹
}
preOrder(root, pre); //求先序
preOrderMirror(root, preM); //求鏡像樹先序
postOrder(root, post); //求後序
postOrderMirror (root, postM); //求鏡像樹後序
if (origin == pre) { //初始序列等於先序序列
printf("YES\n");
for (int i = 0; i < post.size(); i++) {
printf ("%d", post[i]);
if(i < post.size() -1)
printf(" ");
}
} else if(origin == preM) { //初始序列等於鏡像樹先序序列
printf("YES\n");
for (int i = 0; i < postM. size(); i++) {
printf("%d", postM[i]);
if(i <postM.size() -1)
printf(" ");
}
} else {
printf("NO\n"); //否則輸出NO
}
return 0;
}