1135. Is It A Red-Black Tree (30)
来源:互联网 发布:mysql导出数据库 编辑:程序博客网 时间:2024/06/04 20:14
题目详情:https://www.patest.cn/contests/pat-a-practise/1135
刚看到这道题的感觉很难,现在做出来了,感觉也就那么回事啊[傲娇脸]!
红黑树满足以下5条性质:
1、节点是红色或者黑色
2、根节点为黑色
3、每个叶节点(NIL节点,空节点)是黑色的
4、每个红色节点的子节点都是黑色的,即不能有两个连续的红色节点
5、从任一节点到其每个叶子的所有路径都包含相同数量的黑色节点
本题中,性质1、3是不用检查,需要检查的性质只有2、4、5。
首先明确,红黑树是一棵平衡二叉树,平衡二叉树是一棵二叉搜索树。那么红黑树满足平衡二叉树和二叉搜索树的性质。我是根据二叉搜索树的性质来还原这棵树的。
性质2只需要判断根节点的政府即可。
性质4用前序遍历检查
性质5用后续遍历来检查
#include <iostream>#include <vector>#include <malloc.h>#include <math.h>#include <string.h>using namespace std;#define N 33typedef struct BTree{ struct BTree* leftBTree; int value; struct BTree* rightBTree;}BTree;BTree* buildBTree(int* pre,int start,int end)//start和end用来限制访问的范围{//根据二叉搜索树的性质和红黑树前序遍历序列来还原红黑树 if (start==end)//起始位置和结束位置相同,那么代表空节点 return NULL; int i; for(i=start;i<end;i++)//找到比pre[start]的第一个位置后停止 {//根据二叉搜索树的性质,该位置右侧的数在右子树上 if( abs(pre[i])>abs(pre[start]) ) break; } BTree* root=(BTree*)malloc(sizeof(BTree));//建立"根节点" root->value=pre[start]; root->leftBTree=buildBTree(pre,start+1,i);//递归建立左子树 root->rightBTree=buildBTree(pre,i,end);//递归建立右子树 return root;}int postOrder(BTree* root)//后续遍历检查路径上是否由相同的黑色节点数量{ if(root!=NULL) { int leftBlack=postOrder(root->leftBTree);//leftBlack存左子树的黑色节点数量 int rightBlack=postOrder(root->rightBTree);//rightBlack存右子树的黑色节点数量 if ( leftBlack<0 || rightBlack<0 || rightBlack!=leftBlack ) return -1; //黑色节点数不相等,或左子树、右子树已经存在不等的黑色节点数则返回一个负数 else if(root->value<0)//本节点为红色,则不加上本节点 return leftBlack; else//本节点为黑色 return leftBlack+1;//加上本黑色节点 } return 0;}int previousOrder(BTree* root) //前序遍历用以检查是否有连续的两个红色节点{ if(root) { if(root->value<0)//本届点为红色节点 { if(root->leftBTree)//左子树非空 { if(root->leftBTree->value<0)//左节点为红色 return 1;//则返回真值(1),代表有连续的红色节点 } if(root->rightBTree)//右子树非空 { if(root->rightBTree->value<0)//右节点为红色 return 1;//则返回真值(1),代表有连续的红色节点 } } return previousOrder(root->leftBTree) || previousOrder(root->rightBTree);//递归进行检查 } return 0;//空节点则返回假值,代表没有连续的两个红色节点}int main(){ int k,n,preOrder[N]; scanf("%d",&k);//输入循环的次数 for(int i=0;i<k;i++) { scanf("%d",&n);//输入节点的个数,n为一个正数 memset(preOrder,0,n);//将preOrder数组的前n个元素全部置为0 for(int j=0;j<n;j++) scanf("%d",&preOrder[j]);//存储前序遍历的序列 if(preOrder[0]<0)//负号代表红色节点,根节点为红色,则不符合要求 {//保证根节点是黑色的 printf("No\n"); continue; } BTree* root=buildBTree(preOrder,0,n);//还原(构建)红黑树 //用后续遍历来判断是否连续的两个节点为红色,路径上的黑色节点数量是否相同 //balance用来存储路径的黑色节点是否相同,非负数相同,负数(-1)代表数量不相同 //continous用来存储两个红色的节点是否连续,1代表连续, int balance=postOrder(root); int continous=previousOrder(root); //如果路径上黑色节点数量不同或者存在连续的红色节点 if( balance<0 || continous==1) printf("No\n"); else printf("Yes\n"); }}
阅读全文
0 0
- 1135. Is It A Red-Black Tree (30)
- PAT甲级 1135. Is It A Red-Black Tree (30)
- 1135. Is It A Red-Black Tree (30)
- 1135. Is It A Red-Black Tree (30)[红黑树判断]
- 1135. Is It A Red-Black Tree (30) 红黑树
- 1135. Is It A Red-Black Tree (30)
- 1135. Is It A Red-Black Tree (30)
- pat1135 Is It A Red-Black Tree (30)(红黑树)
- PAT 1135. Is It A Red-Black Tree (30) 二叉搜索树建立 + 红黑树判断
- 【PAT 1135. Is It A Red-Black Tree (30)】& 二叉树
- 1135. Is It A Red-Black Tree (30)-PAT甲级真题
- 1135. Is It A Red-Black Tree (30)(判断红黑树)
- PAT甲级1135 Is It A Red-Black Tree
- PAT (Advanced Level) Practise 1135Is It A Red-Black Tree (30)
- PAT-1135 Is It A Red-Black Tree(二叉查找树的创建和遍历)
- Is It A Tree?
- Is it a tree?
- Is It A Tree?
- SpringBoot导入XML
- 19_二叉树的镜像
- 原生ajax剖析
- ssh原理(转载)
- OpenCV和VS2015开发环境配置
- 1135. Is It A Red-Black Tree (30)
- 初学者学习复习day_3
- Servlet 传输中文乱码原理及解决方法
- Java:求二叉树中节点的最大距离
- 洛谷 P3106 [USACO14OPEN]GPS的决斗Dueling GPS's
- python正则表达式——30张图入门
- 网易云热评 《十年》
- BZOJ 3156 防御准备 动态规划+斜率优化
- Android studio生成apk时自动追加版本号