红黑树

红黑树

定义

红黑树是一种特殊的二叉查找树,红⿊黑树不是⼀种AVL树,红黑树相对于AVL树来说,牺牲了部分平衡性以换取插入/删除操作时少量的旋转操作,整体来
说性能要优于AVL树。

特性

  • 每个节点不是红色就是黑色
  • 红色节点的孩子节点一定是黑色
  • 根节点都是黑色(入度为0的节点一定是黑色)
  • 每个节点到后代的所有简单路径中包含相同数量的黑色节点
  • 每个叶子节点都是黑色(树中的叶子节点是是空节点即NULL)— 因此这个可以不需要判断

PAT 1135
在这里插入图片描述

判断是否是红黑树

#include <iostream>
using namespace std;
const int mmax = 40;
struct Node
{
    int dt;
    Node * lchild;
    Node * rchild;
};
int k;
Node * creat(Node * root,int v)
{
    if(root == NULL)
    {
        root = new Node;
        root->dt = v;
        root->lchild = root->rchild = NULL;
        return root;
    }
    if(abs(root->dt) > abs(v))  root->lchild = creat(root->lchild,v);
    else if(abs(root->dt) <abs(v)) root->rchild = creat(root->rchild,v);
    return root;
}
/*根据建立的树,从根结点开始遍历,如果当前结点是红色,判断它的孩子节点是否为黑⾊,递
归返回结果*/
bool judge1(Node * node)
{
    if(node == NULL) return true;
    if(node->dt < 0)
    {
        if(node->lchild != NULL && node->lchild->dt < 0) return false;
        if(node->rchild != NULL && node->rchild->dt < 0) return false;
    }
    return judge1(node->lchild)&&judge1(node->rchild);
}

int getnum(Node * node)
{
    if(node == NULL) return 0;
    int l = getnum(node->lchild);
    int r = getnum(node->rchild);
    return node->dt>0? max(l,r)+1 : max(l,r);
}
/*从根节点开始,递归遍历,检查每个结点的左子树的⾼度和右子树的⾼度(这里的高度指黑色
结点的个数),比较左右孩子高度是否相等,递归返回结果*/
bool judge2(Node * node)
{
    if(node == NULL) return true;
    int l = getnum(node->lchild);
    int r = getnum(node->rchild);
    if(l == r) return judge2(node->lchild)&&judge2(node->rchild);
    return false;
}
int main()
{
    cin>>k;
    int n,pre[mmax];
    while(k--)
    {
        cin>>n;
        Node * root = NULL;
        for(int i=0; i<n; i++)
        {
            cin>>pre[i];
            root = creat(root,pre[i]);
        }
        if(pre[0]<0||!judge1(root)||!judge2(root))
        {
            cout<<"No"<<endl;
        }
        else cout<<"Yes"<<endl;
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值