A1135 | 红黑树判断:审题、根据“先序遍历”和“BST树”的条件生成后序遍历、递归判断
对A1135这题有心里阴影了,今天终于拿下AC。学习自柳神博客:https://www.liuchuo.net/archives/4099
首先读题很关键:
There is a kind of balanced binary search tree named red-black tree in the data structure………………
红黑树首先应该是一棵BST树,不然从何谈起维护二分查找结构?
所以第一步就应该根据先序遍历以及BST树的特性来判断是否是一棵BST树,然后根据这两个条件生成树形链式结构。
柳神博客中给出的方法是生成后序遍历然后判断size是否与先序遍历的长度相等。笔者认为生成一个新的先序遍历然后判断长度也可以。
void getPost(int root,int end){//create a BST by pre order and BST's property
if(root>end) return;
int i=root+,j=end;
while(i<=end && pre[root]>pre[i]) i++;
while(j>=root+ && pre[root]<pre[j]) j--;
if(i!=j+) return;
getPost(root+,j);
getPost(i,end);
post.push_back(pre[root]);
}
以上是生成后序遍历的代码。代码逻辑:
7 2 1 5 4 11 8 14 16
j↑ ↑i
让i->遍历[root + 1 , 大于root的数],j<-遍历[小于root的数 , end]
然后二者相互错开,建立新的递归关系。
特殊边界条件:
1
\
2
\
3
这个结构符合BST树的定义,先序遍历是 123。
第一轮:
1 2 3
j i
第二轮:
2 3
j i
第三轮:
3
ij
然后再谈到递归判断。两个递归判断代码:
int getNum(Node* node){
if(!node) return ;
int l=getNum(node->l);
int r=getNum(node->r);
int m=max(l,r);
if(!node->isR) m++;
return m;
}
bool judge1(Node* node){//every path to leaves have same black
if(!node) return true;
if(getNum(node->l)!=getNum(node->r)) return false;
return judge1(node->l) && judge1(node->r);
}
bool judge2(Node* node){//the node is red , the both leaves is black
if(!node) return true;
if(node->isR){
if(node->l && node->l->isR) return false;
if(node->r && node->r->isR) return false;
}
return judge2(node->l) && judge2(node->r);
}
完整代码:
#include <stdio.h>
#include <memory.h>
#include <math.h>
#include <string>
#include <vector>
#include <set>
#include <stack>
#include <queue>
#include <algorithm>
#include <map> #define I scanf
#define OL puts
#define O printf
#define F(a,b,c) for(a=b;a<c;a++)
#define FF(a,b) for(a=0;a<b;a++)
#define FG(a,b) for(a=b-1;a>=0;a--)
#define LEN 10000
#define MAX 0x06FFFFFF
#define V vector<int> using namespace std; V post;
V pre;
typedef struct Node{
int d=;
bool isR=true;
struct Node* l=NULL;
struct Node* r=NULL;
Node(int D,int I){
d=D;isR=I;
l=NULL;r=NULL;
}
}Node; Node *root=NULL; void getPost(int root,int end);
Node* bst_insert(Node* p,int d);
bool judge1(Node* node);
bool judge2(Node* node); int main() {
freopen("d:/input/A1135/1.txt","r",stdin);
int N,M,i;
scanf("%d",&N);
while(N-->){
scanf("%d",&M);
pre.resize(M);
post.clear();
root=NULL;
FF(i,M){
int t;
scanf("%d",&t);
pre[i]=abs(t);
root=bst_insert(root,t);
}
getPost(,M-);
if(post.size()!=M){
OL("No");continue;
}
if(root->isR){
OL("No");continue;
}
if(judge1(root) && judge2(root))
OL("Yes");
else OL("No");
}
// OL("OK");
return ;
} void getPost(int root,int end){//create a BST by pre order and BST's property
if(root>end) return;
int i=root+,j=end;
while(i<=end && pre[root]>pre[i]) i++;
while(j>=root+ && pre[root]<pre[j]) j--;
if(i!=j+) return;
getPost(root+,j);
getPost(i,end);
post.push_back(pre[root]);
} Node* bst_insert(Node* p,int d){
Node* node=new Node(abs(d),d<);//if d < 0 , d is red
if(!p){//node is null
return node;
}else{
int v=abs(d);
if(v>p->d){//r
if(p->r){
p->r=bst_insert(p->r,d);
}else{
p->r=node;
}
}else{
if(p->l){
p->l=bst_insert(p->l,d);
}else{
p->l=node;
}
}
}
return p;
} int getNum(Node* node){
if(!node) return ;
int l=getNum(node->l);
int r=getNum(node->r);
int m=max(l,r);
if(!node->isR) m++;
return m;
} bool judge1(Node* node){//every path to leaves have same black
if(!node) return true;
if(getNum(node->l)!=getNum(node->r)) return false;
return judge1(node->l) && judge1(node->r);
} bool judge2(Node* node){//the node is red , the both leaves is black
if(!node) return true;
if(node->isR){
if(node->l && node->l->isR) return false;
if(node->r && node->r->isR) return false;
}
return judge2(node->l) && judge2(node->r);
}
A1135 | 红黑树判断:审题、根据“先序遍历”和“BST树”的条件生成后序遍历、递归判断的更多相关文章
- PAT甲题题解-1119. Pre- and Post-order Traversals (30)-(根据前序、后序求中序)
(先说一句,题目还不错,很值得动手思考并且去实现.) 题意:根据前序遍历和后序遍历建树,输出中序遍历序列,序列可能不唯一,输出其中一个即可. 已知前序遍历和后序遍历序列,是无法确定一棵二叉树的,原因在 ...
- 数据结构与算法--从平衡二叉树(AVL)到红黑树
数据结构与算法--从平衡二叉树(AVL)到红黑树 上节学习了二叉查找树.算法的性能取决于树的形状,而树的形状取决于插入键的顺序.在最好的情况下,n个结点的树是完全平衡的,如下图"最好情况&q ...
- 【Java入门提高篇】Day25 史上最详细的HashMap红黑树解析
当当当当当当当,好久不见,最近又是换工作,又是换房子,忙的不可开交,断更了一小段时间,最重要的一篇迟迟出不来,每次都犹抱琵琶半遮面,想要把它用通俗易懂的方式进行说明,确实有一定的难度,可愁煞我也,但自 ...
- AVL树与红黑树
平衡树是平时经常使用数据结构. C++/JAVA中的set与map都是通过红黑树实现的. 通过了解平衡树的实现原理,可以更清楚的理解map和set的使用场景. 下面介绍AVL树和红黑树. 1. AVL ...
- Java集合详解6:TreeMap和红黑树
Java集合详解6:TreeMap和红黑树 初识TreeMap 之前的文章讲解了两种Map,分别是HashMap与LinkedHashMap,它们保证了以O(1)的时间复杂度进行增.删.改.查,从存储 ...
- 史上最详细的HashMap红黑树解析
简介:请允许我当一回标题党.好了,言归正传,本篇主要内容便是介绍HashMap的男二号——TreeNode(男一号还是给Node吧,毕竟是TreeNode的爷爷,而且普通节点一般来说也比TreeN ...
- Bzoj3227 [Sdoi2008]红黑树(tree)
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 204 Solved: 125 Description 红黑树是一类特殊的二叉搜索树,其中每个结点被染 ...
- 算法导论 第十三章 红黑树(python)-1插入
红黑树是上一章二叉搜索树的改进,实现一种平衡 ,保证不会出现二叉树变链表的情况,基本动态集合操作的时间复杂度为O(lgn) 实际用途:c++stl中的set,map是用他实现的 红黑树的性质: 1.每 ...
- 红黑树之 原理和算法详细介绍(阿里面试-treemap使用了红黑树) 红黑树的时间复杂度是O(lgn) 高度<=2log(n+1)1、X节点左旋-将X右边的子节点变成 父节点 2、X节点右旋-将X左边的子节点变成父节点
红黑树插入删除 具体参考:红黑树原理以及插入.删除算法 附图例说明 (阿里的高德一直追着问) 或者插入的情况参考:红黑树原理以及插入.删除算法 附图例说明 红黑树与AVL树 红黑树 的时间复杂度 ...
随机推荐
- 基于Mybatis-Plus实现自动化操作创建时间和修改时间
引入 在实际开发中,总会避免不了操作数据库,而在数据库中每个表都会有create_time和update_time字段记录操作时间,我们在操作这两个时间的时候也可能会出现不一致的情况,或者说这两个字段 ...
- Oracle的视图和索引
学习笔记: ##视图 * 概念:视图就是提供一个查询的窗口,所有数据来自于原表. * 方法: * 查询语句创建表: * create table ...
- vs2019 netocore项目本地程序ip地址访问需修改的配置文件
IISPress启动项目后,打开IISPress托盘可以看到当前项目 根据图中标识出来的applicationhost.config文件路径,一般为你的项目解决方案目录下的.vs\解决方案文件夹\co ...
- java基础小练习,1-打印一百次(1~10)的随机数,2-固定一个随机数(1~100),然后猜出他,3-定义以指定格式打印集合(ArrayList类型作为参数),使用{}括起来,使用@代替,分隔每个元素
推荐自己码一下,可以使用别的方法,面向对象,不需要注重过程 /* 题目:我需要打印一百次(1~10)的随机数 */ import java.util.Random; public class demo ...
- Python与Golang对比
一:前言 刚看了一篇软文,说什么“才华是改变人生最有效的途径”,反正呢,大体就是科技进步,要想一直在车上,就得不断的学习,刚好最近也准备学习Golang,最近火的不能在火了吧,刚好也有些Python基 ...
- 2019-07-30 ThinkPHP文件上传
文件上传就是获取到待上传文件的临时路径,把它移动到服务器下的相应文件夹中. 文件上传,必须在表单中的form标签中写入:enctype="multipart/form-data" ...
- android解析xml (pull)
1. xml <persons> <person id="18"> <name>furong</name> <age>2 ...
- es倒排索引原理解析
倒排索引原理 普通的存储方式是给每个文档编一个序号 然后让这个序号对应单个文档的所有内容 如果用这样的方式查找 当需要查找某个单词的时候需要遍历所有的文档集合 查找文档的效率会非常的慢 2.基本 ...
- day 28
目录 操作系统发展史 穿孔卡片 联机批处理系统 脱机批处理系统 多道技术(基于单核情况下研究) 单道 多道技术 并发与并行 进程 程序与进程 进程调度 先来先服务调度 短作业优先调度 时间片轮转法 分 ...
- k8s之StatefulSet介绍(六)
复制有状态的Pod replicaSet通过一个pod模版创建多个pod副本.这些副本除了它们的名字和IP地址不同外,没有别的差异.如果pod模版里描述了一个关联到特定持久卷声明的数据卷,那么Repl ...