当前位置:网站首页>PAT 甲级 A1043 Is It a Binary Search Tree
PAT 甲级 A1043 Is It a Binary Search Tree
2022-07-15 14:02:00 【柘木木】
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 (≤1000). 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;
思路:思路很清晰了,先建立二叉查找树,并保存其插入序列,然后就对该二叉树进行求先序遍历序列和后序遍历序列,也对镜面二叉查找树作相同操作(因为没有建立镜面二叉查找树,根据镜面二叉树的性质更改遍历条件即可),先序遍历和插入序列对比,对就输出后序序列反之输出NO。
代码:
#include<iostream>
#include<vector>
using namespace std;
int n,weight;
vector<int > oripre,pre,oripost,post,origin;
struct node{
int data;
node* lchild;//指针定义不能单单用逗号隔开用来定义多个指针如node*
node* rchild;
};
void insert(node* &root,int x){//插入并建立二叉查找树,记得使用&;
if(root==NULL){//递归边界;
root=new node;//是root=new node而不是node* root=new node,root已经定义过了不能重新定义,不然会覆盖原来root指针;
root->data=x;
root->lchild=NULL;
root->rchild=NULL;
return ;
}else if(x>=root->data){//一般等于是插左边的,但是题目规定插右边,插左边和插右边的先序遍历结果是不一样的,注意这一点;
insert(root->rchild,x);//递归式;
}else{
insert(root->lchild,x);
}
}
void oripreorder(node* root,vector<int > &vi){//二叉查找树的遍历,传入函数的只是副本,要对数组值进行操作就需要&;
if(root==NULL)return ;
vi.push_back(root->data);
oripreorder(root->lchild,vi);
oripreorder(root->rchild,vi);
}
void preorder(node* root,vector<int > &vi){//镜面二叉查找树的先序遍历,还是用原来的那个平衡二叉树,遍历顺序变成根右左就好了;
if(root==NULL)return ;
vi.push_back(root->data);
preorder(root->rchild,vi);
preorder(root->lchild,vi);
}
void oripostorder(node* root,vector<int > &vi){//原二叉查找树的后序遍历;
if(root==NULL)return ;
oripostorder(root->lchild,vi);
oripostorder(root->rchild,vi);
vi.push_back(root->data);
}
void postorder(node* root,vector<int > &vi){
if(root==NULL)return ;
postorder(root->rchild,vi);
postorder(root->lchild,vi);
vi.push_back(root->data);
}
int main( ){
scanf("%d",&n);
node* root=new node;
root=NULL;
for(int i=0;i<n;i++){
scanf("%d",&weight);
origin.push_back(weight);
insert(root,weight);//都是从根节点出发,找到查找失败的结点就是要插入的地方;
}
//建立好了二叉查找树;
oripreorder(root,oripre);//求二叉查找树的先序遍历;
preorder(root,pre);//镜像二叉查找树的先序遍历,用同一棵树遍历的方式不同;
if(oripre==origin){//二叉查找树的插入顺序等于二叉查找树的先序遍历;
printf("YES\n");
oripostorder(root,oripost);
for(int i=0;i<oripost.size();i++){
printf("%d",oripost[i]);
if(i!=oripost.size()-1)printf(" ");
}
}else if(pre==origin){//镜像二叉查找树的先序遍历序列等于插入序列;
printf("YES\n");
postorder(root,post);
for(int i=0;i<post.size();i++){
printf("%d",post[i]);
if(i!=post.size()-1)printf(" ");
}
}else {
printf("NO");
}
return 0;
}注意:
1.
一般是左子树的值小于或者等于根节点的值,右子树大于根节点的值,但是题目有要求就按照题目要求建树,因为等于的结点在左边和在右边其遍历出来的序列是不一样的,如插入序列为
8 6 7 5 10 8 11的二叉查找树,如果是等于在左边则先序遍历序列为:8 6 5 7 8 10 11
如果等于在右子树则先序遍历序列为:8 6 7 5 10 8 11,所以要看好题目要求。
2.
传入函数的是数组的副本,用完即销毁,在函数内对该副本进行操作不会对原数组造成影响,因此要想在函数改变数组值,需要用引用,传入该数组的地址,直接对该数组进行操作;
3.
二叉查找树的插入是对整个二叉树的结构造成影响,即子结点的建立会改变递归上一层的父节点的child指向,因此root需要用到引用,使得子结点建立后并更新父节点的指向。
4.
两个vector可以直接赋值和比较是否相等,不需要要像一般数组一样需要用循环赋值,比较,将vector成变量就好了,变量可以直接赋值和比较。
边栏推荐
- 1301_两种方式为开发板增加串口监控功能
- Creative ribbon style landing page
- JVM memory model -- Characteristics and functions of runtime data area
- DEDECMS织梦上一篇下一篇自由可控输出链接、标题、缩略图、时间
- 工业以太网交换机的产品性能有哪些呢?
- 四剑客与Code Review的恩怨情仇:“始乱终弃”到“浪子回头”
- JS image editor plug-in filerobot
- MySQL8.0学习记录18 - Tablespaces
- 启牛商学院股票开户安全吗靠谱吗,启牛怎么还能开户呢
- Leetcode-31-next spread
猜你喜欢

ThreadLocal原理及源码解析(一步一步点进去,不要背了,学思想)

JS figure guess fruit and vegetable games code

盘点波卡生态潜力项目 | 跨链特性促进多赛道繁荣

Life cycle of class

Neural network loss and ACC drawing method plot

SaaS application: the best way to realize enterprise digital transformation

GPU distributed training

MIMX8MD6CVAHZAB I.MX 8MDUAL Cortex-A53 - 微处理器

面试题:谈谈你对AQS 的理解

创意丝带样式登录页面
随机推荐
Interprocess communication -- signal principle and detailed explanation
SaaS application: the best way to realize enterprise digital transformation
Flock's yarn clustering mode (1)
LM-Nav:基于语言、视觉和行为大模型的机器人导航方法
#yyds干货盘点# 解决名企真题:循环数比较
Seven suggestions on knowledge management in the construction of enterprises and institutions
惯性导航原理(七)-IMU误差分类(下)-Allan方差分析方法+IMU测试+标定简介
Pythia:Facebook最新开源的视觉、语言多任务学习框架
假如需求拆分像切蛋糕一样简单 | 敏捷实践
MGRE comprehensive experiment
Deploy eshopondapr on Tencent cloud eks
如何通过特殊数据类型索引实现内存数据库加速
Intel IPU
Machine learning - matrix derivation basic formula + common formula
Pytorch分布式训练
【走进go的内心深处】
leetcode 605. Can Place Flowers 种花问题 (简单)
四剑客与Code Review的恩怨情仇:“始乱终弃”到“浪子回头”
gradle 打包排除依赖 排除文件
太卷了, 某公司把自家运营多年的核心系统(智慧系统)完全开源了....