A Binary Search Tree (BST) is recursively defined as a binary tree which has the following properties:

  • 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.
  • Both the left and right subtrees must also be binary search trees.

If we swap the left and right subtrees of every node, then the resulting tree is called the Mirror Image of a BST.

Now given a sequence of integer keys, you are supposed to tell if it is the preorder traversal sequence of a BST or the mirror image of a BST.

Input Specification:

Each input file contains one test case. For each case, the first line contains a positive integer N (≤). Then N integer keys are given in the next line. All the numbers in a line are separated by a space.

Output Specification:

For each test case, first print in a line YES if the sequence is the preorder traversal sequence of a BST or the mirror image of a BST, or NO if not. Then if the answer is YES, print in the next line the postorder traversal sequence of that tree. All the numbers in a line must be separated by a space, and there must be no extra space at the end of the line.

Sample Input 1:

7
8 6 5 7 10 8 11

Sample Output 1:

YES
5 7 6 8 11 10 8

Sample Input 2:

7
8 10 11 8 6 7 5

Sample Output 2:

YES
11 8 10 7 5 6 8

Sample Input 3:

7
8 6 8 5 10 9 11

Sample Output 3:

NO

题意
给出N个正整数来作为一棵二叉排序树的结点插入顺序,问:这串序列是否是该二叉排序树的先序序列或是该二叉排序树的镜像树的先序序列。所谓镜像树是指交换二叉树的所有结点的左右子树而形成的树(也即左子树所有结点数据域大于或等于根结点,而根结点数据域小于右子树所有结点的数据域)。如果是镜像树,则输出YES,并输出对应的树的后序序列;否则,输出NO。

 #include<bits/stdc++.h>
using namespace std;
struct Node{//树结点
int data;
Node*left,*right;
Node(int d):data(d),left(nullptr),right(nullptr){}
};
void insertNode(Node*&root,int data,bool mirror){//插入结点,构建二叉查找树或其镜像树
if(root==nullptr)//根指针指向空节点
root=new Node(data);//建立新节点
else if(data<root->data&&!mirror)//如果不是镜像树且数据域比根节点的数据小
insertNode(root->left,data,mirror);//向左子树插入
else if(data<root->data&&mirror)//如果是镜像树且数据域比根节点的数据小
insertNode(root->right,data,mirror);//向右子树插入
else if(data>=root->data&&!mirror)//如果不是镜像树且数据域比根节点的数据大或相等
insertNode(root->right,data,mirror);//向右子树插入
else if(data>=root->data&&mirror)//如果是镜像树且数据域比根节点的数据大或相等
insertNode(root->left,data,mirror);//向左子树插入
}
void preOrder(Node*root,vector<int>&order){//求先根遍历
order.push_back(root->data);
if(root->left!=nullptr)
preOrder(root->left,order);
if(root->right!=nullptr)
preOrder(root->right,order);
}
void postOrder(Node*root,vector<int>&order){//求后根遍历
if(root->left!=nullptr)
postOrder(root->left,order);
if(root->right!=nullptr)
postOrder(root->right,order);
order.push_back(root->data);
}
int main(){
int N;
scanf("%d",&N);
vector<int> order,pre(N);
Node*root=nullptr;
for(int i=;i<N;++i)
scanf("%d",&pre[i]);
for(int i=;i<N;++i)//构建二叉查找树或其镜像树
if(pre.size()>=&&pre[]>pre[])
insertNode(root,pre[i],true);
else
insertNode(root,pre[i],false);
preOrder(root,order);//求构建的树先根遍历序列
if(equal(pre.cbegin(),pre.cend(),order.cbegin())){//c++标准库自带的判断两个容器元素是否对应相等
order.clear();
postOrder(root,order);//求后根遍历序列
printf("YES\n");
for(int i=;i<order.size();++i)
printf("%s%d",i>?" ":"",order[i]);
}else
printf("NO");
return ;
}

这道题只要求求出后根遍历序列,我们可以通过二叉查找树的先根遍历序列直接得出后根遍历序列。

按照第一个样例对算法进行阐述:

1.先根序列为:8 6 5 7 10 8 11

当前后根序列为空

可以确定8是整棵树的根节点,由于6 5 7小于8;8 10 11大于等于8,按照二叉查找树的性质可知6 5 7是8的左子树,10 8 11是8的右子树。由于后根序列是“左右中”顺序,先处理左子树6 5 7

2. 先根序列为6 5 7

当前后根序列为空

可以确定6是整棵子树的根节点,由于5小于6;7大于6,按照二叉查找树的性质可知5是6的左子树,7是6的右子树。由于后根序列是“左右中”顺序,先处理左子树5

3.先根序列为5

当前后根序列为空

可以确定5是叶子结点,放入后根遍历序列中,返回第2步中处理的子树中

4.先根序列为6 5 7

当前后根序列为5

左子树处理完毕,处理右子树7

5.先根遍历序列为7

当前后根遍历序列为5

可以确定7是叶子结点,放入后根遍历序列中,返回第4步中处理的子树中

6.先根遍历序列为6 5 7

当前后根遍历序列为5 7

左右子树均处理完成,将根节点6放入后根遍历序列中,返回第1步处理的树中

7.先根序列为:8 6 5 7 10 8 11

当前后根遍历序列为5 7 6

左子树处理完毕,处理右子树10 8 11

8.先根序列为10 8 11

当前后根遍历序列为5 7 6

可以确定10是整棵子树的根节点,由于8小于10,11大于10,按照二叉查找树的性质可知8是10的左子树,11是10的右子树。由于后根序列是“左右中”顺序,且左右子树均为叶子结点,按8 11 10的顺序将三个结点数据值放入后根遍历序列中,返回到第7步处理的子树中

9.先根序列为:8 6 5 7 10 8 11

当前后根遍历序列为5 7 6 8 11 10

左右子树均处理完成,将根节点8放入后根遍历序列中,算法结束

镜像树求后根遍历序列的算法与之相同,只需做稍许修改。如果输入序列的长度>=2并且第2个数比第一个数小,那么输入的就应该是一棵二叉查找树;否则是一棵镜像树。对于无法构成二叉查找树和镜像树的序列,在进行上述算法时可以提前返回,通过判断得出的后根遍历序列中元素个数与给定的元素总数是否相等来判断是否是无法构成二叉查找树和镜像树的序列。具体方式可见代码。

 #include<bits/stdc++.h>
using namespace std;
vector<int>post,pre();
bool mirror=false;//是否是镜像树
void postOrder(int left,int right){
if(left>right)
return;
int i=left+,j=right;//i指示右子树的第一个数在先根遍历序列中的索引,j指示左子树的最后一个数在先根遍历序列中的索引
if(!mirror) {
while(i<=right&&pre[left]>pre[i])
++i;
while(j>left&&pre[left]<=pre[j])
--j;
}else{
while(i<=right&&pre[left]<=pre[i])
++i;
while(j>left&&pre[left]>pre[j])
--j;
}
if(i-j!=) return ;//i-j!=1,说明不能构成二叉查找树或镜像树,提前返回
postOrder(left+,i-);//处理左子树
postOrder(i,right);//处理右子树
post.push_back(pre[left]);//将根节点加入后根遍历序列中
}
int main(){
int N;
scanf("%d",&N);
for(int i=;i<N;++i)
scanf("%d",&pre[i]);
if(N>&&pre[]>pre[])//判断是否是镜像树
mirror=true;
postOrder(,N-);//得出后根遍历序列
if(post.size()==N){//得出的后根遍历序列中元素个数与给定的元素总数相等,说明能构成二叉查找树或镜像树
printf("YES\n");
for(int i=;i<post.size();++i)
printf("%s%d",i>?" ":"",post[i]);
}else//得出的后根遍历序列中元素个数与给定的元素总数相等,说明不能构成二叉查找树或镜像树
printf("NO");
return ;
}

PAT甲级——A1043 Is It a Binary Search Tree的更多相关文章

  1. PAT 甲级 1043 Is It a Binary Search Tree

    https://pintia.cn/problem-sets/994805342720868352/problems/994805440976633856 A Binary Search Tree ( ...

  2. PAT 甲级 1043 Is It a Binary Search Tree (25 分)(链表建树前序后序遍历)*不会用链表建树 *看不懂题

    1043 Is It a Binary Search Tree (25 分)   A Binary Search Tree (BST) is recursively defined as a bina ...

  3. 【PAT甲级】1099 Build A Binary Search Tree (30 分)

    题意: 输入一个正整数N(<=100),接着输入N行每行包括0~N-1结点的左右子结点,接着输入一行N个数表示数的结点值.输出这颗二叉排序树的层次遍历. AAAAAccepted code: # ...

  4. A1043. Is It a Binary Search Tree

    A Binary Search Tree (BST) is recursively defined as a binary tree which has the following propertie ...

  5. A1043 Is It a Binary Search Tree (25 分)

    A Binary Search Tree (BST) is recursively defined as a binary tree which has the following propertie ...

  6. 【PAT】1043 Is It a Binary Search Tree(25 分)

    1043 Is It a Binary Search Tree(25 分) A Binary Search Tree (BST) is recursively defined as a binary ...

  7. A1043 Is It a Binary Search Tree (25 分)

    A Binary Search Tree (BST) is recursively defined as a binary tree which has the following propertie ...

  8. PAT Advanced 1043 Is It a Binary Search Tree (25) [⼆叉查找树BST]

    题目 A Binary Search Tree (BST) is recursively defined as a binary tree which has the following proper ...

  9. PAT (Advanced Level) 1099. Build A Binary Search Tree (30)

    预处理每个节点左子树有多少个点. 然后确定值得时候递归下去就可以了. #include<cstdio> #include<cstring> #include<cmath& ...

随机推荐

  1. H2数据库的基本使用

    文章目录 下载jar包 启动服务 下载jar包 下载h2-1.3.176.jar 这个包(部分服务版本不一致,请自行更换版本) 启动服务 从终端定位到刚才jar包下载的位置,比如我这里是Downloa ...

  2. day 72 Django基础七之Ajax

    Django基础七之Ajax   本节目录 一 Ajax简介 二 Ajax使用 三 Ajax请求设置csrf_token 四 关于json 五 补充一个SweetAlert插件(了解) 六 同源策略与 ...

  3. Mysql优化系列之查询性能优化前篇3(必须知道的几个事实)

    事实一:临时表没有任何索引 最常见的临时表莫过于在from子句中写子查询,遇到这种情况,Mysql会先将其查询结果放到一张临时表中, 然后将这个临时表当做普通表对待 事实二:执行计划优化 大多数的sq ...

  4. windows系统下jupyter notebook使用虚拟环境

    目录 [亲测好使]windows系统下jupyter notebook使用虚拟环境 在虚拟环境中安装jupyter,并添加到jupyter kernel 参考 [未测试,但觉得比上面那方法好,因为上面 ...

  5. POJ - 2778 ~ HDU - 2243 AC自动机+矩阵快速幂

    这两题属于AC自动机的第二种套路通过矩阵快速幂求方案数. 题意:给m个病毒字符串,问长度为n的DNA片段有多少种没有包含病毒串的. 根据AC自动机的tire图,我们可以获得一个可达矩阵. 关于这题的t ...

  6. java_缓冲流(字节输入流)

    /** * java.iko.BufferedInputStream extends InputStream * BufferedInputStream:字节缓冲输入流 * 构造方法: * Buffe ...

  7. iOS逆向系列-逆向APP思路

    界面分析 通过Cycript.Reveal. 对于Reveal安装配置可参考配置iOS逆向系列-Reveal 通过Reveal找到内存中的UI对象 静态分析 开发者编写的所有代码最终编译链接到Mach ...

  8. Foundation框架系列-NSArray

    NSArray常用API 数组字符串指定字符拼接 // 将数组中的元素以separator拼接返回字符串 比如@[@"a=1", @"b=2"] 以separa ...

  9. 7款外观迷人的HTML5/CSS3 3D特效按钮特效

    下面我整理了7款外观都十分迷人的HTML5/CSS3 3D按钮特效,有几个还挺实用的,分享给大家. 1.CSS3超酷3D弹性按钮 按钮实现非常简单 之前我们分享过几款不错的CSS3 3D立体按钮,比如 ...

  10. sed 批量替换文件

    1.想把某个目录下包含only-upstage的文件都替换成onlyu-base sed  -i -e 's/onlyu-upstage/onlyu-base/g'  ` grep -rl onlyu ...