PAT 1043 Is It a Binary Search Tree[二叉树][难]
1043 Is It a Binary Search Tree(25 分)
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 Ninteger 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
题目大意:如初一系列数,如果它是给出一棵二叉搜索树的前根遍历或者是它的左右子数反转的二叉树的前根便利(关键字会重复出现), 那么就输出Yes,并且输出这棵二叉树的后根遍历,如果不是输出No。
//建立一棵树,存储,使用数组存储。
代码来自:https://www.liuchuo.net/archives/2153
#include <cstdio>
#include <vector>
using namespace std;
bool isMirror;
vector<int> pre, post;
void getpost(int root, int tail) {
if(root > tail) return ;
int i = root + , j = tail;
if(!isMirror) {
while(i <= tail && pre[root] > pre[i]) i++;
//这个i一直循环到右子树的根节点,因为root的右子树是>pre[root]的。
while(j > root && pre[root] <= pre[j]) j--;
//这个是找到左子树前序遍历的最后一个节点。
} else {
while(i <= tail && pre[root] <= pre[i]) i++;
while(j > root && pre[root] > pre[j]) j--;
}
if(i - j != ) return ;
getpost(root + , j);//遍历左子树,
getpost(i, tail);//遍历右子树
post.push_back(pre[root]);//后根遍历放进来。
//当时叶节点的时候,会在入口处的if直接return了。
}
int main() {
int n;
scanf("%d", &n);
pre.resize(n);
for(int i = ; i < n; i++)
scanf("%d", &pre[i]);//输入前序。
getpost(, n - );//获取后序,
if(post.size() != n) {
isMirror = true;
post.clear();
getpost(, n - );
}
if(post.size() == n) {//如果是正常搜索二叉树的话,应该是=n的,有这么个规律在的。
printf("YES\n%d", post[]);//0直接在这里输出。
for(int i = ; i < n; i++)
printf(" %d", post[i]);
} else {
printf("NO");
}
return ;
}
//柳神的应该是能AC的代码中最精简的了,不用建树,厉害,之前也见到过这样的题目,应该加深一下,学习了。
//正常来说的思路就是,建树,所以参考了以下代码,也十分整洁:https://www.nowcoder.com/questionTerminal/8bcd661314744321b55dce1c1bfa8c54
//全是套路==
#include <cstdio>
#include <vector>
using namespace std;
struct Node{
int value;
Node *left, *right;//用的是指针哟。
}; void Insert(Node* &root, int data){//今天自己建树不成功才发现, 原来这位大佬传的是指针的引用,只传指针是不行的,学习了!2018-9-7
if(root == NULL){
root = new Node;//新指向一个节点。
root -> value = data;
root -> left = NULL;
root -> right = NULL;
return;
}
if(data < root->value) Insert(root->left, data);
else Insert(root->right, data);//由此看来>=root都是放在右子树的。
} void PreOrder(Node* root, vector<int>& v){
if(root == NULL) return;
v.push_back(root->value);//先访问根节点,再左右子树。
PreOrder(root->left, v);
PreOrder(root->right, v);
} void PreMirrorOrder(Node* root, vector<int>& v){
if(root == NULL) return;
v.push_back(root->value);
PreMirrorOrder(root->right, v);
PreMirrorOrder(root->left, v);
} void PostOrder(Node* root, vector<int>& v){//注意这里传了引用,其实也可以将其设置为全局变量。
if(root == NULL) return;
PostOrder(root->left, v);
PostOrder(root->right, v);
v.push_back(root->value);
} void PostMirrorOrder(Node* root, vector<int>& v){
if(root == NULL) return;
PostMirrorOrder(root->right, v);//既然右边小,那么就先访问右边
PostMirrorOrder(root->left, v);//再访问左边,形成的是和正常地是一样的序列。
v.push_back(root->value);
} int main(){
int n;
Node* s = NULL;
scanf("%d", &n);
vector<int> num, pre, preM, post, postM;
for(int i=; i<n; i++){
int data;
scanf("%d", &data);
num.push_back(data);
Insert(s, data);//使用指针传递,第一次就不是null了.
//此处建树最终建成的是一个标准的搜索二叉树。
}
PreOrder(s, pre);
if(num == pre){//判断两个向量是否相等,直接判断就可以了。
PostOrder(s, post);
printf("YES\n");
for(unsigned int i=; i<post.size(); i++){
printf("%d", post[i]);
if(i < post.size()-) printf(" ");
}
}
else{
PreMirrorOrder(s, preM);
if(num == preM){
PostMirrorOrder(s, postM);
printf("YES\n");
for(unsigned int i=; i<postM.size(); i++){
printf("%d", postM[i]);
if(i < postM.size()-) printf(" ");
}
}
else printf("NO\n");
}
return ;
}
//这个感觉是正常地思路。
1.首先按输入序列,建成一个标准的二叉搜索树,并且保存输入序列为num(题目中给的也是前序遍历)。
2.然后对其进行前序遍历,得到结果pre;
3.此时将pre与输入序列对比,如果=,那么就是正常的二叉搜索树
4.否则就可能是镜像或者完全不是两者。
5.此时对二叉树进行镜像前序遍历(因为镜像也就是将左右子树反转,那么此时访问根节点后,再访问建好的二叉树的右子树不就相当于对镜像进行前序遍历了吗)
6.得到的结果是preM,如果和num相同那么就是镜像的,然后对其进行后序镜像遍历输出
7.否则不是二者,输出no.
//厉害,学习了,建树的过程,以及前序和后序遍历,都明白了,多复习!
PAT 1043 Is It a Binary Search Tree[二叉树][难]的更多相关文章
- PAT 1043 Is It a Binary Search Tree (25分) 由前序遍历得到二叉搜索树的后序遍历
题目 A Binary Search Tree (BST) is recursively defined as a binary tree which has the following proper ...
- PAT 1064 Complete Binary Search Tree[二叉树][难]
1064 Complete Binary Search Tree (30)(30 分) A Binary Search Tree (BST) is recursively defined as a b ...
- PAT 1043 Is It a Binary Search Tree
#include <cstdio> #include <climits> #include <cstdlib> #include <vector> co ...
- 【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 ...
- 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 ...
- PAT甲级:1064 Complete Binary Search Tree (30分)
PAT甲级:1064 Complete Binary Search Tree (30分) 题干 A Binary Search Tree (BST) is recursively defined as ...
- PAT 甲级 1043 Is It a Binary Search Tree
https://pintia.cn/problem-sets/994805342720868352/problems/994805440976633856 A Binary Search Tree ( ...
- 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 ...
- PAT题库-1064. Complete Binary Search Tree (30)
1064. Complete Binary Search Tree (30) 时间限制 100 ms 内存限制 32000 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHE ...
随机推荐
- 国外大神说:在编程中使用If语句的潜在危险
大多数编程语言中if语句主要有两个作用:验证输入以保护域免受错误数据的影响,以及处理域内业务逻辑.但是,Udi Dahan最近在阿姆斯特丹DDD欧洲会议上的发言中指出,我们一般很 当我们查看系 ...
- 3th January 2014
I owe my girl so much, i want to pay her, i know this is impossible,but I still try hard.
- C# 哈希加密
1.方法一: [c-sharp] view plaincopy //适用于C#语言 //使用前需导入以下命名空间:using System.Web.Security; //第一个参数为需加密的字符串, ...
- visual studio 2017使用NHibernate4.0连接oracle11g数据库
之前一直是公司用NHibernate2.1来做项目,连接oracle 10g的数据库,配置NHibernate的东西都是以前的同事做好了的,也怪自己太懒了,没尝试过配置这个东西,虽然一直在使用NHib ...
- JQuery--使用autocomplete控件进行自己主动输入完毕(相当于模糊查询)
之前为了实现这个功能花了我几天的时间. 事实上.实现了之后发现也就那么回事,正所谓万事开头难嘛.. 废话不多说了.这里我使用的是JQuery控件库中的一个Autocomplete控件.即Autocom ...
- day24<多线程>
多线程(多线程的引入) 多线程(多线程并行和并发的区别) 多线程(Java程序运行原理和JVM的启动是多线程的吗) 多线程(多线程程序实现的方式1) 多线程(多线程程序实现的方式2) 多线程(实现Ru ...
- Leetcode: Best Time to Buy and Sell Stock I, II
思路: 1. 算法导论讲 divide and conquer 时, 讲到过这个例子. 书中的做法是先让 price 数组减去一个值, 然后求解最大连续子数组的和. 分治算法的复杂度为 o(nlogn ...
- centos6 安装 directAdmin
注:教程参考 https://bbs.aliyun.com/read/159390.html 这篇文章来操作就可以了 需要注意的地方是 1)directAdmin 需要一个纯净的环境,安装direct ...
- Runtime 中的 _cmd、 IMP
IMP IMP-指向实际执行函数体的函数指针 #if !OBJC_OLD_DISPATCH_PROTOTYPES typedef void (*IMP)(void /* id, SEL, ... */ ...
- 【PHP】php 生成条形码
1.什么是条形码? 百度百科定义:条形码(barcode)是将宽度不等的多个黑条和空白,按照一定的编码规则排列,用以表达一组信息的图形标识符.常见的条形码是由反射率相差很大的黑条(简称条)和白条(简称 ...