<数据结构>XDOJ332.二叉排序树的判定
问题与解答
问题描述
给定一个二叉树,判断其是否是一个有效的二叉排序树。
假设一个二叉排序树具有如下特征:
结点的左子树只包含小于当前结点的树。
结点的右子树只包含大于当前结点的树。
所有左子树和右子树自身必须也是二叉排序树。
输入格式
第一行两个数n,root,分别表示二叉树有n个结点,第root个结点是二叉树的根。接下来共n行,第i行三个数val_i、left_i、right_i,分别表示第i个结点的值val是val_i,左儿子left是第left_i个结点,右儿子right是第right_i个结点。
节点0表示空。
1<=n<=100000,保证是合法的二叉树
输出格式
输出"true"如果给定二叉树是二叉排序树,否则输出"false"
样例输入
5 1
5 2 3
1 0 0
3 4 5
4 0 0
6 0 0
样例输出
false
#include<stdio.h>
#define MAXSIZE 1000001 //最大结点数
typedef struct { //结构体表示结点
int val; //结点值
int lchild; //结点左子树位置
int rchild; //结点右子树位置
}Node;
Node data[MAXSIZE]; //结构体数组表示树
int Judge( Node data); //递归方法,判断是否为二叉排序树
int main (void) {
int n, root, i, j, val_i, left_i, right_i, flag;
scanf ("%d %d", &n, &root); //输入结点数和根节点位置
for (i = 1; i <= n; i++) { //建立树
scanf ("%d %d %d", &val_i, &left_i, &right_i);
data[i].val = val_i;
data[i].lchild = left_i;
data[i].rchild = right_i;
}
flag = Judge (data[root]); //调用Judge函数
if (flag) {
printf ("true\n");
}
else {
printf ("false\n");
}
return 0;
}
int Judge(Node p) {
if (p.lchild == 0 && p.rchild == 0) return 1; //终止条件,到达叶子结点
//判断当前结点是否满足排序树条件
if (p.lchild != 0 && p.val <= data[p.lchild].val //存在左子树且结点值小于左子树的值
|| p.rchild != 0 && p.val >= data[p.rchild].val) //存在右子树且结点值大于右子树的值
return 0; //若不满足,返回0
else { //若满足:
if(p.lchild != 0) return Judge(data[p.lchild]); //递归判断左子树
if(p.rchild != 0) return Judge(data[p.rchild]); //递归判断右子树
}
}
题后反思
- 在判断当前结点与左右子树的关系时,需要先确定左右子树存在。即不能遗漏
p.lchild != 0
否则当前结点不存在左或右子树时,还会继续和data[0].val进行比较进而导致程序错误。 Judge(data[p.lchild])
前需要return
。