★实验任务
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;
}