码迷,mamicode.com
首页 > 其他好文 > 详细

A1135 | 红黑树判断:审题、根据“先序遍历”和“BST树”的条件生成后序遍历、递归判断

时间:2017-12-29 23:40:36      阅读:345      评论:0      收藏:0      [点我收藏+]

标签:display   特殊   new   后序   bool   scan   class   关系   arc   

对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+1,j=end;
    while(i<=end && pre[root]>pre[i]) i++;
    while(j>=root+1 && pre[root]<pre[j]) j--;
    if(i!=j+1) return;
    getPost(root+1,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 0;
    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=0;
    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-->0){
        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(0,M-1);
        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 0;
}

void getPost(int root,int end){//create a BST by pre order and BST‘s property
    if(root>end) return;
    int i=root+1,j=end;
    while(i<=end && pre[root]>pre[i]) i++;
    while(j>=root+1 && pre[root]<pre[j]) j--;
    if(i!=j+1) return;
    getPost(root+1,j);
    getPost(i,end);
    post.push_back(pre[root]);
}

Node* bst_insert(Node* p,int d){
    Node* node=new Node(abs(d),d<0);//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 0;
    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);
}
View Code

 

A1135 | 红黑树判断:审题、根据“先序遍历”和“BST树”的条件生成后序遍历、递归判断

标签:display   特殊   new   后序   bool   scan   class   关系   arc   

原文地址:https://www.cnblogs.com/TQCAI/p/8146471.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!