1. 程式人生 > >是否二叉搜尋樹(25 分)

是否二叉搜尋樹(25 分)

習題4.3 是否二叉搜尋樹(25 分)

本題要求實現函式,判斷給定二叉樹是否二叉搜尋樹。

函式介面定義:

bool IsBST ( BinTree T );

其中BinTree結構定義如下:

typedef struct TNode *Position;
typedef Position BinTree;
struct TNode{
    ElementType Data;
    BinTree Left;
    BinTree Right;
};

函式IsBST須判斷給定的T是否二叉搜尋樹,即滿足如下定義的二叉樹:

定義:一個二叉搜尋樹是一棵二叉樹,它可以為空。如果不為空,它將滿足以下性質:

  • 非空左子樹的所有鍵值小於其根結點的鍵值。
  • 非空右子樹的所有鍵值大於其根結點的鍵值。
  • 左、右子樹都是二叉搜尋樹。

如果T是二叉搜尋樹,則函式返回true,否則返回false。

裁判測試程式樣例:

#include <stdio.h>
#include <stdlib.h>

typedef enum { false, true } bool;
typedef int ElementType;
typedef struct TNode *Position;
typedef Position BinTree;
struct TNode{
    ElementType Data;
    BinTree Left;
    BinTree Right;
};

BinTree BuildTree(); /* 由裁判實現,細節不表 */
bool IsBST ( BinTree T );

int main()
{
    BinTree T;

    T = BuildTree();
    if ( IsBST(T) ) printf("Yes\n");
    else printf("No\n");

    return 0;
}
/* 你的程式碼將被嵌在這裡 */

輸入樣例1:如下圖

輸出樣例1:

Yes

輸入樣例2:如下圖

輸出樣例2:

No
作者: DS課程組單位: 浙江大學時間限制: 400ms記憶體限制: 64MB程式碼長度限制: 16KB

折騰了很久,寫出如下程式碼。

bool IsBST ( BinTree T ){
    if((!T)||(!T->Left)&&(!T->Right)) return true;
    else if(!(IsBST(T->Left))&&(IsBST(T->Right))) return false;
    else if(!(T->Left?T->Data>T->Left->Data:1)&&(T->Right?T->Data<T->Right->Data:1)) return false;
    else {
      BinTree TLeft, TRight;
      if(T->Left) {
        TLeft = T->Left;
        while(TLeft->Right) TLeft = TLeft->Right;
      }
      if(T->Right){
        TRight = T->Right;
        while(TRight->Left) TRight= TRight->Left;
      }
      
      return (T->Left?(T->Data>TLeft->Data):1)&&(T->Right?(T->Data<TRight->Data):1);
    }
}

需要注意的一些測試點:

空樹是二叉搜尋樹;只有一個節點的樹也是二叉搜尋樹;

左右子樹至少有一個非空,先判定左右子樹是否都為二叉搜尋樹(遞迴),如果該條件不滿足肯定不是;

左右子樹都是二叉搜尋樹。假如左子樹或右子樹為空,則該端不用考慮,邏輯為1即可;如果非空,找到左子樹的最右節點和右子樹最左節點。要求左子樹最右節點數值<根節點數值<右子樹最左節點數值。注意如果有一邊的子樹為空,就不能對T->Left或者T->賦值了,否則會段錯誤