对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]

然后二者相互错开,建立新的递归关系。

特殊边界条件:

  \

   2

     \

      3

这个结构符合BST树的定义,先序遍历是 123。

第一轮:

1 2 3

j i

第二轮:

2 3

j i

第三轮:

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树”的条件生成后序遍历、递归判断的更多相关文章

  1. PAT甲题题解-1119. Pre- and Post-order Traversals (30)-(根据前序、后序求中序)

    (先说一句,题目还不错,很值得动手思考并且去实现.) 题意:根据前序遍历和后序遍历建树,输出中序遍历序列,序列可能不唯一,输出其中一个即可. 已知前序遍历和后序遍历序列,是无法确定一棵二叉树的,原因在 ...

  2. 数据结构与算法--从平衡二叉树(AVL)到红黑树

    数据结构与算法--从平衡二叉树(AVL)到红黑树 上节学习了二叉查找树.算法的性能取决于树的形状,而树的形状取决于插入键的顺序.在最好的情况下,n个结点的树是完全平衡的,如下图"最好情况&q ...

  3. 【Java入门提高篇】Day25 史上最详细的HashMap红黑树解析

    当当当当当当当,好久不见,最近又是换工作,又是换房子,忙的不可开交,断更了一小段时间,最重要的一篇迟迟出不来,每次都犹抱琵琶半遮面,想要把它用通俗易懂的方式进行说明,确实有一定的难度,可愁煞我也,但自 ...

  4. AVL树与红黑树

    平衡树是平时经常使用数据结构. C++/JAVA中的set与map都是通过红黑树实现的. 通过了解平衡树的实现原理,可以更清楚的理解map和set的使用场景. 下面介绍AVL树和红黑树. 1. AVL ...

  5. Java集合详解6:TreeMap和红黑树

    Java集合详解6:TreeMap和红黑树 初识TreeMap 之前的文章讲解了两种Map,分别是HashMap与LinkedHashMap,它们保证了以O(1)的时间复杂度进行增.删.改.查,从存储 ...

  6. 史上最详细的HashMap红黑树解析

      简介:请允许我当一回标题党.好了,言归正传,本篇主要内容便是介绍HashMap的男二号——TreeNode(男一号还是给Node吧,毕竟是TreeNode的爷爷,而且普通节点一般来说也比TreeN ...

  7. Bzoj3227 [Sdoi2008]红黑树(tree)

    Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 204  Solved: 125 Description 红黑树是一类特殊的二叉搜索树,其中每个结点被染 ...

  8. 算法导论 第十三章 红黑树(python)-1插入

    红黑树是上一章二叉搜索树的改进,实现一种平衡 ,保证不会出现二叉树变链表的情况,基本动态集合操作的时间复杂度为O(lgn) 实际用途:c++stl中的set,map是用他实现的 红黑树的性质: 1.每 ...

  9. 红黑树之 原理和算法详细介绍(阿里面试-treemap使用了红黑树) 红黑树的时间复杂度是O(lgn) 高度<=2log(n+1)1、X节点左旋-将X右边的子节点变成 父节点 2、X节点右旋-将X左边的子节点变成父节点

    红黑树插入删除 具体参考:红黑树原理以及插入.删除算法 附图例说明   (阿里的高德一直追着问) 或者插入的情况参考:红黑树原理以及插入.删除算法 附图例说明 红黑树与AVL树 红黑树 的时间复杂度 ...

随机推荐

  1. Java 8 HashMap 源码解析

    HashMap 使用数组.链表和红黑树存储键值对,当链表足够长时,会转换为红黑树.HashMap 是非线程安全的. HashMap 中的常量 static final int DEFAULT_INIT ...

  2. SQL Server优化之SET STATISTICS开关(转载)

    一.准备工作 缓存对于某个查询的性能影响十分之大,所以优化之前要清空缓存. 清除Buffer Pool里面的所有缓存 DBCC DROPCLEANBUFFERS 清除Buffer Pool里的所有缓存 ...

  3. lazyload的使用方法

    http://blog.csdn.net/peidandan/article/details/8107634

  4. Oracle使用中的常规操作总结

    写一篇在使用Oracle过程中一些常用的操作,以便于忘记的时候查看 一.创建用户和给用户赋予权限 create user 用户名 identified by 密码; --12c一下版本 create ...

  5. node_exporte新版本指标名称变化说明

    changelog如下 Breaking changes This release contains major breaking changes to metric names. Many metr ...

  6. JavaScript 数组(一)数组基础

    一.数组 1.概述 数组 就是将多个元素按一定顺序排放到一个集合中,那么这个集合称之为数组. 数组 也是一种数据类型,属于复杂数据类型(Object). 2.特点 存放的元素有序的. 可以存放不同的数 ...

  7. adb shell get/setprop, setenforce...

    adb shell getprop <key> 获取设备参数信息adb shell setprop <key> <value> 设置设备参数信息 例子1:>C ...

  8. iOS 关于NavigationController返回的一些笔记

    1.理解NavigationController返回机制 一般NavigationController下的子view只有一层或者有很多层,子view返回最顶层则可以直接用 [self.navigati ...

  9. 12306 抢票项目霸榜 GitHub,标星即将破万

    十一将至,你买到回家的火车票了吗?如果没有,你可以试着打开 GitHub,在搜索栏键入 12306 的关键词,我相信你会发现一个新大陆.没错,这里有 1572 个抢票项目.它们大多用 Python.J ...

  10. Echarts实现Excel趋势线和R平方计算思路

    测试数据 [19550, 7.1 ],[22498, 8.44 ],[25675, 9.56 ],[27701, 10.77],[29747, 11.5 ],[32800, 12.27],[34822 ...