本题要求实现函数,判断给定二叉树是否二叉搜索树。
函数接口定义:
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
法一:
分析:
用一个数组来模拟栈来进行中序遍历法,然后另一数组存出栈的数据,在判断储存的序列是否是递增的,如果是递增的输出Yes,如果不是就输出No。
注意:
用数组模拟栈的时候,出栈时要先取栈顶元素,然后删除数组里的栈顶元素,同时下标也要后退。
代码:
bool IsBST ( BinTree T )
{
int flag=-1;
//中序法得到顺序序列,用一个数组模拟栈,另一个数组储存出栈的数据
BinTree BT;
BinTree a[100]={NULL};//模拟栈
BinTree b[100]={NULL};//储存出栈的数据
int ai,bi;
ai=bi=0;
BT=T;
while(BT||ai!=0)//链表不为NULL或a[]中有数据
{
while(BT)//沿着左子树一直储存经过的数据
{
a[ai]=BT;
ai++;
BT=BT->Left;
}
if(a[ai-1]==NULL)//跳过为空的节点,这样得到的序列是连续的,没有间断的
{
ai--;
}
b[bi]=a[ai-1];//储存出栈的节点
BT=a[ai-1];//把要出栈的节点赋给BT(取栈顶节点)
a[ai-1]=NULL;//模拟出栈(删除栈顶节点)
bi++;
ai--;//下标后退
BT=BT->Right;
}
//判断是否为二叉树,直接判断序列内的数是否是递增
for(int i=1;b[i]!=NULL;i++)
{
if((b[i-1]->Data)>=(b[i]->Data))
{
flag=0;//不是搜索二叉树
break;
}
}
if(flag==-1)
flag=1;
if(flag==0)//不是搜索二叉树
return false;
else//是搜索二叉树
return true;
}
法二:
代码
//方法:根据二叉树搜索树的性质,当左子树中的最大值小于根结点且右子树的最小值大于根结点时,可确定一棵二叉搜索树
bool IsBST(BinTree T) {
BinTree L, R ,L1 ,R1;
if (!T) return true; // 空树是BST
if (!T->Right && !T->Left) return true; // 叶子节点是BST
L = L1 = T->Left;
R = R1 = T->Right;
if (L) {
// 遍历左子树找到最右边的节点
while (L->Right) L = L->Right;
// 检查左子树的最大值是否小于根节点的值
if (L->Data > T->Data) return false;
}
if (R) {
// 遍历右子树找到最左边的节点
while (R->Left) R = R->Left;
// 检查右子树的最小值是否大于根节点的值
if (R->Data < T->Data) return false;
}
// 递归检查左右子树是否也是BST
return IsBST(L1) && IsBST(R1);
}