递归判断+建树

题目链接:https://www.patest.cn/contests/gplt/L2-004

题解

二叉搜索树的特点就是其根节点的值是位于左右子树之间的,即大于左子树的所有值,但是小于等于右子树的所有值。而先序遍历的序列,第一个值就是其根的值,我们可以利用这些性质来递归判断一棵树是否为二叉搜索树。

首先,遍历这个序列,找到第一个大于等于根节点值的节点,如果从这个节点开始之后的所有节点的值都是大于等于根节点的,那么这棵树就是二叉搜索树。而二叉搜索树的“镜像”也可以利用这种思想进行判断。

如果是一棵二叉搜索树或者是其镜像,我们就可以开始建树,建树之后可以递归的输出其后序遍历序列。

代码如下:

  1. #include<cstdio>
  2. #include<vector>
  3. using namespace std;
  4. const int maxn = 1000+10;
  5. struct Node {
  6. int value;
  7. Node *lson, *rson;
  8. Node():lson(NULL),rson(NULL){}
  9. }*root;
  10. int n;
  11. int s[maxn];
  12. vector<int> ans;
  13. //当kind为true,代表进行二叉搜索树的判断,当kind为false,代表进行二叉搜索树镜像判断
  14. bool _test(bool kind, int L, int R) {
  15. if(L >= R)return true;
  16. int i;
  17. for(i = L+1; i <= R; i++) {
  18. if(kind) {
  19. if(s[L] <= s[i]) {
  20. break;
  21. }
  22. }else {
  23. if(s[L] > s[i]) {
  24. break;
  25. }
  26. }
  27. }
  28. bool flag = true;
  29. for(int j = i; j <= R; j++) {
  30. if(kind) {
  31. if(s[j] < s[L]){
  32. flag = false;
  33. }
  34. }else {
  35. if(s[j] >= s[L]) {
  36. flag = false;
  37. }
  38. }
  39. }
  40. if(flag) {
  41. return _test(kind, L+1, i-1) && _test(kind, i, R);
  42. }else {
  43. return false;
  44. }
  45. }
  46. Node* _build(bool kind, int L, int R) {
  47. if(L > R) return NULL;
  48. int i;
  49. for(i = L+1; i <= R; i++) {
  50. if(kind) {
  51. if(s[L] <= s[i]) {
  52. break;
  53. }
  54. }else {
  55. if(s[L] > s[i]) {
  56. break;
  57. }
  58. }
  59. }
  60. Node *p = new Node();
  61. p->value = s[L];
  62. p->lson = _build(kind, L+1, i-1);
  63. p->rson = _build(kind, i, R);
  64. return p;
  65. }
  66. void post_order(Node *p) {
  67. if(p != NULL) {
  68. post_order(p->lson);
  69. post_order(p->rson);
  70. ans.push_back(p->value);
  71. }
  72. }
  73. void out_put() {
  74. post_order(root);
  75. int len = ans.size();
  76. for(int i = 0; i < len; i++) {
  77. if(i) printf(" ");
  78. printf("%d", ans[i]);
  79. }
  80. printf("\n");
  81. }
  82. int main() {
  83. scanf("%d", &n);
  84. for(int i = 0; i < n; i++) {
  85. scanf("%d", &s[i]);
  86. }
  87. int flag = 0;
  88. if(_test(true, 0, n-1)) {
  89. flag = 1;
  90. root = _build(true, 0, n-1);
  91. }else if(_test(false, 0, n-1)) {
  92. flag = 2;
  93. root = _build(false, 0, n-1);
  94. }
  95. if(flag != 0) {
  96. puts("YES");
  97. out_put();
  98. }else {
  99. puts("NO");
  100. }
  101. return 0;
  102. }

PAT 天梯赛 L2-004 这是二叉搜索树吗?的更多相关文章

  1. PAT天梯赛练习题 L3-010. 是否完全二叉搜索树(完全二叉树的判断)

    L3-010. 是否完全二叉搜索树 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 陈越 将一系列给定数字顺序插入一个初始为空的二叉搜 ...

  2. 天梯赛练习 L3-010 是否完全二叉搜索树 (30分) 数组建树模拟

    题目分析: 本题的要求是将n个数依次插入一个空的二叉搜索树(左大右小,且没有重复数字),最后需要输出其层次遍历以及判断是否是完全二叉搜索树,通过观察我们发现, 如果这个树是用数组建立的,那么最后输出的 ...

  3. PAT 天梯赛 L1-017. 到底有多二 【水】

    题目链接 https://www.patest.cn/contests/gplt/L1-017 AC代码 #include <iostream> #include <cstdio&g ...

  4. PAT天梯赛L2-004 这是二叉搜索树吗【递归】

    L2-004. 这是二叉搜索树吗? 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 陈越 一棵二叉搜索树可被递归地定义为具有下列性质的 ...

  5. PAT 天梯赛 是否完全二叉搜索树   (30分)(二叉搜索树 数组)

    将一系列给定数字顺序插入一个初始为空的二叉搜索树(定义为左子树键值大,右子树键值小),你需要判断最后的树是否一棵完全二叉树,并且给出其层序遍历的结果. 输入格式: 输入第一行给出一个不超过20的正整数 ...

  6. PAT 天梯赛 是否同一棵二叉搜索树   (25分)(二叉搜索树 指针)

    给定一个插入序列就可以唯一确定一棵二叉搜索树.然而,一棵给定的二叉搜索树却可以由多种不同的插入序列得到.例如分别按照序列{2, 1, 3}和{2, 3, 1}插入初始为空的二叉搜索树,都得到一样的结果 ...

  7. pat 团体天梯赛 L3-010. 是否完全二叉搜索树

    L3-010. 是否完全二叉搜索树 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 陈越 将一系列给定数字顺序插入一个初始为空的二叉搜 ...

  8. pat 团体天梯赛 L2-004. 这是二叉搜索树吗?

    L2-004. 这是二叉搜索树吗? 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 陈越 一棵二叉搜索树可被递归地定义为具有下列性质的 ...

  9. PAT 天梯赛 L3-010. 是否完全二叉搜索树 【Tree】

    题目链接 https://www.patest.cn/contests/gplt/L3-010 思路 因为是 完全二叉搜索树 可以用 数据 建树的方式 然后 遍历一遍这个 数字 就是 层序遍历 遍历的 ...

随机推荐

  1. oracle数据库字符集的修改

    本文摘自:http://blog.csdn.net/nsj820/article/details/65711051.改客户端字符集:通过WINDOWS的运行菜单运行Regedit,修改注册表 Star ...

  2. TortoiseGit保存用户名密码的方法

    方法一: 设置 -> git 编辑本地 .git/config 增加 1 [credential]    2     helper = store 保存,输入一次密码后第二次就会记住密码了 方法 ...

  3. 第一次安装ubuntu要设置的东西

    1. 安装网卡驱动 lscpi 查看网卡型号 根据型号找到驱动源码 下载下来并编译 安装 2. 编译安卓源码的时候出现jdk型号不对的情况 把/usr/bin/java 删除,就可以了.

  4. SQLServer在多个表中都增加一个字段的方法

    1.使用游标 declare @sql varchar(), @name varchar() declare my_cursor scroll cursor for select name from ...

  5. Bookmark

    http://stackoverflow.com/https://www.baidu.com/?tn=06074089_27_pghttp://apistore.baidu.com/http://to ...

  6. MyEclipse 2015 运行tomcat 内存溢出的解决方法

    内存溢出错误: 2016-3-16 11:19:55 org.apache.catalina.core.StandardWrapperValve invoke严重: Servlet.service() ...

  7. 【多重背包模板】poj 1014

    #include <iostream> #include <stdio.h> #include <cstring> #define INF 100000000 us ...

  8. 转Android 用Animation-list实现逐帧动画

    Android 用Animation-list实现逐帧动画     第一步:先上图片素材,以下素材放到res/drawable目录下: http://blog.csdn.net/aminfo/arti ...

  9. 字段为空sql语句,设置当前模式

    delete from t_corpinfo  where CORPID='' and CORPNAME=''  该命令是删除字段为空的记录 SET CURRENT SCHEMA DB2INST1;

  10. 学习笔记——组合模式Composite

    组合模式,典型的层次结构. 与装饰器类图相似. 区别在于:装饰器模式是为了在接口中增加方法,而组合模式在于层次元素的叠加. ConcreteComponent就是中间结点,可以包含更多的Concret ...