zoukankan      html  css  js  c++  java
  • 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+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
  • 相关阅读:
    匿名函数
    Ajax
    Mysql 数据库操作
    Linux下查看apache连接数
    c++ 当输入的数据不符合数据类型时,清理输入流
    c++ 将输入存储到数组,然后反转数组,最后输出
    c++ 递归求一个数的阶乘
    c++ 计算彩票中奖概率
    c++ 结构体,设置物品体积并输出物品属性
    c++ 输入10个数,显示它的平均分
  • 原文地址:https://www.cnblogs.com/TQCAI/p/8146471.html
Copyright © 2011-2022 走看看