<資料結構>XDOJ332.二叉排序樹的判定
阿新 • • 發佈:2021-12-22
問題與解答
問題描述
給定一個二叉樹,判斷其是否是一個有效的二叉排序樹。
假設一個二叉排序樹具有如下特徵:
結點的左子樹只包含小於當前結點的樹。
結點的右子樹只包含大於當前結點的樹。
所有左子樹和右子樹自身必須也是二叉排序樹。
輸入格式
第一行兩個數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
。