L2-004. 这是二叉搜索树吗?
2016-07-10 22:23
344 查看
题目链接是:
https://www.patest.cn/contests/gplt/L2-004
题解:
根节点的值是位于左右子树之间的,即大于左子树的所有值,但是小于等于右子树的所有值。
而先序遍历的序列,第一个值就是其根的值,我们可以利用这些性质来递归判断一棵树是否为二叉搜索树。
首先,遍历这个序列,找到第一个大于等于根节点值的节点,如果从这个节点开始之后的所有节点的值都是大于等于根节点的,那么这
棵树就是二叉搜索树。而二叉搜索树的“镜像”也可以利用这种思想进行判断。
如果是一棵二叉搜索树或者是其镜像,我们就可以开始建树,建树之后可以递归的输出其后序遍历序列。
代码及注释:
https://www.patest.cn/contests/gplt/L2-004
题解:
根节点的值是位于左右子树之间的,即大于左子树的所有值,但是小于等于右子树的所有值。
而先序遍历的序列,第一个值就是其根的值,我们可以利用这些性质来递归判断一棵树是否为二叉搜索树。
首先,遍历这个序列,找到第一个大于等于根节点值的节点,如果从这个节点开始之后的所有节点的值都是大于等于根节点的,那么这
棵树就是二叉搜索树。而二叉搜索树的“镜像”也可以利用这种思想进行判断。
如果是一棵二叉搜索树或者是其镜像,我们就可以开始建树,建树之后可以递归的输出其后序遍历序列。
代码及注释:
#include <iostream> #include <cstdio> #include <vector> using namespace std; const int maxn = 1000+10; struct Node { int value; Node *lson, *rson; Node():lson(NULL),rson(NULL){} }*root; int n; int s[maxn]; vector<int> ans; //按序记录后序遍历的元素,因为在后序遍历输出时不能控制最后的空格 //判断 kind为true判断原树,为false判断镜像 bool test(bool kind, int L, int R) { if(L >= R) return true; int i; for(i = L+1; i <= R; i++) { if(kind) { if(s[L] <= s[i]) break; //到 i-1 为止为左子树 } else { if(s[L] > s[i]) break; } } bool flag = true; for(int j = i; j <= R; j++) { if(kind) { if(s[j] < s[L]) flag = false; //若右子树有小于根结点值的直接返回 false } else { if(s[j] >= s[L]) flag = false; } } if(flag) return test(kind, L+1, i-1) && test(kind, i, R); //一直递归分治下去 else return false; } Node* create(bool kind, int L, int R) { if(L > R) return NULL; int i; for(i = L+1; i <= R; i++) { if(kind) { if(s[L] <= s[i]) break; //到i-1为止为左子树 } else { if(s[L] > s[i]) break; } } Node *p = new Node(); p->value = s[L]; p->lson = create(kind, L+1, i-1); //递归建立左子树 p->rson = create(kind, i, R); //递归建立右子树 return p; } void postOrderTraverse(Node *p) { if(p) { postOrderTraverse(p->lson); postOrderTraverse(p->rson); ans.push_back(p->value); } } void Print() { postOrderTraverse(root); int len = ans.size(); for(int i = 0; i < len-1; i++) printf("%d ", ans[i]); printf("%d\n", ans[len-1]); } int main() { scanf("%d", &n); for(int i = 0; i < n; i++) scanf("%d", &s[i]); int flag = 0; if(test(true, 0, n-1)) { flag = 1; root = create(true, 0, n-1); } else if(test(false, 0, n-1)) { flag = 2; root = create(false, 0, n-1); } if(flag != 0) { puts("YES"); Print(); } else puts("NO"); return 0; }
相关文章推荐
- 在宇宙间不易被风吹散 —— 金星
- 局部内部类能访问非final类型局部变量?
- 最简洁的中断现场保护
- 嵌入式开发为什么选择C语言?
- 巩固基础篇:八皇后问题:经典回溯法
- jvm垃圾收集器配置-1
- C++中临时对象及返回值优化
- Python 从入门到放弃系列 一:Python基本元素(数字,字符串)
- 详解:这段代码为什么不进中断?
- 菜鸟学java开篇
- OpenGL::由实例讲解概念
- 《OpenGL ES 2.0 Programming Guide》第12章“Framebuffer Objects”示例代码【C语言版】
- Linux设备驱动之USB hub驱动
- sift readme
- 改编版K9F2G08U0A程序
- 对于makefile的初步的理解
- 欢迎使用CSDN-markdown编辑器
- 文件压缩
- 在宇宙间不易被风吹散 —— 火星
- Java 用自定义类型作为HashMap的键