算法与数据结构实验题 6.25 地鼠安家 1

★实验任务

fd 是一个公认的美丽校园。一天,fd 来了一群地鼠,编号为 1 到 n,他们希望 在这里定居。现在先由第一只地鼠往下打一个单位的距离,并且在那里安家。对 于每一个已经安家的地鼠,如果他左下或右下没有邻居,那还没安家的地鼠就可 以在他的左下或者右下安家。地鼠们已经建完所有的窝了,他们评价这些窝合格 的标准是它们能不能形成一颗二叉搜索树。现在需要你帮助他们评估一下他们的 窝挖的是否合格。

★数据输入

第 1 行一个整数 n,表示地鼠总共 n 只。接下来一共 n 行,每一行三个数:l,o,r,其中 l 表示编号为 o 的地鼠的左邻居的编号,r 表示的是编号为 o 的右邻居的编号,如果没有左 邻居或右邻居,则 l 或 r 为-1。1<=n<=10000。

★数据输出

输出一行,如果如果他们的窝合格,则输出安居在最深的窝的地鼠离地面的距离,如果不合格,则输出-1。

输入示例
5
-1 1 -1
1 2 3
-1 3 -1
2 4 5
-1 5 -1
输出示例

3

 

#pragma GCC optimize(2)		//开O2优化 
#include <cstdio>
#include <cstdlib>
#define MAX 10001
//定义二叉树的结点 
typedef struct btnode *btlink;
typedef struct btnode{
	int element;				
	btlink left;		//左子树
	btlink right;		//右子树 
	int l;		//左邻居的序号 		前期建树的时候用到 
	int r;		//右邻居的序号 
}Btnode;

btlink NewNode()
{
	btlink node = (btlink)malloc(sizeof(btnode));
	node->left = node->right = NULL;
	node->element = 0;
	return node;
}

int flag=0;			//判断是否二叉搜索树   该值仅在InOrder中用到 
//中序遍历 	传入一个结点 以及前一个结点的值 
void InOrder(btlink t)
{
	if(t!=NULL&&flag!=1){
		InOrder(t->left);
		if(t->left!=NULL&&(t->element < t->left->element)){
			flag = 1;
		}
		if(t->right!=NULL&&(t->element > t->right->element)){
			flag = 1;
		}
		InOrder(t->right); 
	}
	return ;
}

int getHeight(btlink t)				//递归求高度 
{
	if(t==NULL)
	 	return 0;
	int leftheight = getHeight(t->left);
	int rightheight = getHeight(t->right);
	return (leftheight>rightheight?(leftheight+1):(rightheight+1));
}
 
int isSon[MAX] = {0};				//这个数组 只存在0 1 两种值 当过儿子就为0, 最后遍历一遍 没当过儿子的就是祖先 
btlink pRatNest[MAX];		//这个数组 存放的是指针, 每个指针都指向一只老鼠序号和下标对应 
//要先建立起鼠巢来 
//想法: 先用一个数组,下标对应序号,存放所有节点,然后再从头到尾遍历一遍,将所有节点连接起来 
int main(void)
{
	int n, i=0;
	int l, o, r; 	//左邻 我 右舍 
	btlink tmp;
	
	scanf("%d", &n);
	//将所有结点按序号放入到数组中 
	for(i=0; i<n; i++){
		scanf("%d %d %d", &l, &o, &r);
	 	tmp = NewNode();
	 	tmp->element = o;
		tmp->l = l;
		tmp->r = r; 
		pRatNest[o] = tmp; 
	}
	//遍历  连接树   设置当过儿子的 
	for(i=1; i<=n; i++){
		//连接左子树 
		if(pRatNest[i]->l!=-1){
			isSon[pRatNest[i]->l] = 1;
			pRatNest[i]->left = pRatNest[pRatNest[i]->l];
		} 	
		else{
			pRatNest[i]->left = NULL;
		}
		//连接右子树 
		if(pRatNest[i]->r!=-1){
			isSon[pRatNest[i]->r] = 1;
			pRatNest[i]->right = pRatNest[pRatNest[i]->r];
		}	
		else{
			pRatNest[i]->right = NULL;
		}
	}
	int root;
	btlink Root = NewNode(); 	//根节点 
	for(i=1 ;i<=n; i++){
		if(isSon[i]==0){
			Root = pRatNest[i]; 
			break;
		}
	}
	InOrder(Root);
	if(!flag){		//如果是二叉搜索树 输出高度 
		printf("%d", getHeight(Root));
	}
	else{
		printf("-1");
	}
	
	return 0;
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值