PAT 1135. Is It A Red-Black Tree (30) 二叉搜索树建立 + 红黑树判断

今天PAT考完试,只做出了3道题,70分。

问题在于读题。

前两题还挺顺利,很快凭借直接做完了,花了50分钟。

第三题卡在题意误解上。  判断的是“各边是否都与 所给集合点 相连” ,而非“各点与各点”相连。 当发现真正题意后,很快就做对了。

第四题最惨,1个小时的时间,有半小时在理解题意上,很短的题目,竟然没注意到“搜索树构建”,只看到“前序序列”。。。

还有,最后其实已经写成功了,就差了一句代码,就是重置根节点——因为这一次有多个输入样例!故搜索树必须重置

只能说命运可能就差了那么一两句代码?


#include<iostream>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<string.h>
#include<cmath>
#include<string>
using namespace std;


//跪在题意理解(搜索树构建)和代码错误
/*************************
题意:
构建二叉搜索树,插入的节点有红黑之分
判断该树是否为红黑树。
*************************/

/************************
求解要点:
1.构建搜索树简单,留意data的比较应该用abs(data)比较
2.判断关键
	①条件1:根节点为黑,即 root->data <0
	②条件2:先遍历一次,若为红色节点,判断其左右孩子是否为红,若为红,输出No。
	③条件3:各点到叶结点的黑色节点数相同。
	用递归做,返回左子树的l1,返回右子树的l2,若l1!=l2,说明不平衡,输出No
	若l1等于l2,则把l1 + (当前是否为黑色点) 的值返回到上一层,即return
	当为空节点即黑色叶子节点时,返回1。
3.易错点:
	因为一次有多个输入样例,故必须“重置树”和“重置标志符号flag”!

************************/

/***********************
笔记:
1.关于树的新建问题,为了保险期间
新建参数中命为 Node* &T,因为刚开始root是没有指向的。
*********************/
#define RH -1
#define LH 1
#define EH 0
#define TRUE 1
#define FALSE 0

struct Node{
	int data;
	Node *lchild,*rchild;
};

struct Node *root;//必须为全局


void insert(Node* &T,int data)
{
	if(T==NULL)
	{
		T = (Node *)malloc(sizeof(Node));
		T->data=data;
		T->lchild=T->rchild=NULL;
		return ;
	}

	if(abs(data)<abs(T->data))
	{
		insert(T->lchild,data);
	}
	else insert(T->rchild,data);
}



bool flag;
void juge1(Node *T)
{
	if(flag==false)
		return ;

	if(T->lchild!=NULL)
	{
		if( T->data<0 && T->lchild->data<0)
		{
			flag=false;
			return ;
		}
		else juge1(T->lchild);
	}

	if(T->rchild!=NULL)
	{
		if( T->data<0 && T->rchild->data<0)
		{
			flag=false;
			return ;
		}
		else juge1(T->rchild);
	}
}

int juge2(Node *T)
{
	int l1,l2;
	if(flag==false)
		return -1;

	if(T==NULL)
		return 1;
	
	l1=juge2(T->lchild);
	l2=juge2(T->rchild);
	
	if(l1!=l2)
	{
		flag=false;
		return -1;
	}
	else
	{
		l1=l1 + (T->data>0);
	}

	return l1;
}


int main()
{
	int k,n,data;
	scanf("%d",&k);
	while(k--)
	{
		flag=true;
		root=NULL;
		scanf("%d",&n);
		while(n--)
		{
			scanf("%d",&data);
			insert(root,data);
		}
		if(root->data<0)
			printf("No\n");
		else
		{
			juge1(root);
			if(flag==false)
			{
				cout<<"No"<<endl;
			}
			else
			{
				juge2(root);
				if(flag==false)
					cout<<"No"<<endl;
				else cout<<"Yes"<<endl;
			}
		}
	}
}



  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值