Loading

<数据结构>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]);  //递归判断右子树
    }
}

题后反思

  1. 在判断当前结点与左右子树的关系时,需要先确定左右子树存在。即不能遗漏p.lchild != 0否则当前结点不存在左或右子树时,还会继续和data[0].val进行比较进而导致程序错误。
  2. Judge(data[p.lchild])前需要return
posted @ 2021-12-22 20:28  咪啪魔女  阅读(806)  评论(0编辑  收藏  举报