分析:
二叉搜索树的特征是左子树的值小于根的值,右子树的值大于根的值。
这里提供三种方法:
方法一:
思路:
如果T非空:
(1)如果T->Left非空
ⅰ.比较T的值和T->Left的大小,若左孩子大,则返回false,表示不是搜索二叉树。
ⅱ.如果T->Left->Right存在的话,就比较T的值和T->Left->Right的大小,如果T->Left->Right比T大那么就返回false,表示不是搜索二叉树。** 注意:这步不能省略,因为只单纯判断左孩子比父亲小,会把左孩子的右孩子大于根结点(即T->Left->Right->Data>T->Data)的情况漏过去,因为根结点的左子树的值都要比根结点小,显然上述情况下搜索二叉树不成立。**
ⅲ.其余情况(表示上述条件满足),则返回IsBST(T->Left)表示继续检查T的左子树——递归思路所在
(2)如果T->Right非空,同左子树操作相似(这里省略不写,可具体看代码)
bool IsBST ( BinTree T )
{
if(T){
if(T->Left){
if(T->Left->Data>T->Data) return false;
if(T->Left->Right){
if(T->Left->Right->Data>T->Data) return false;
}
else return IsBST ( T->Left );
}
if(T->Right){
if(T->Right->Data<T->Data) return false;
if(T->Right->Left){
if(T->Right->Left->Data<T->Data) return false;
}
else return IsBST ( T->Right );
}
}
return true; /*如果结点为空或者是叶子节点这两种情况也是搜索二叉树,
也需要返回true,因为都返回true这里不单独判断,直接
给return true*/
}
方法二:
思路:
(1)找到左子树最大的结点,来和根结点比值的大小,如果左子树的最大值比根大就返回false。
(2)找到右子树最小的结点,来和根结点比值的大小,如果右子树的最小值比根小就返回false。
(3)其余情况就满足是二叉搜索树。
bool IsBST ( BinTree T )
{
if(T){
if(!IsBST(T->Left)||!IsBST(T->Right)) return false;
BinTree B=T->Left;
while(B&&B->Right) B=B->Right;
if(B&&B->Data>T->Data) return false;
BinTree S=T->Right;
while(S&&S->Left) S=S->Left;
if(S&&S->Data<T->Data) return false;
}
return true;
}
方法三
思路:
中序遍历的顺序是左(L)根(N)右(R),而其值的大小为左(L)< 根(N)< 右(R),此时设置一个全局指针B,来判断是否根值比左大,比右小。它是这样判断的,左孩子和父亲判断大小时,B指向左孩子,T指向父亲,右孩子和父亲判断大小时,B指向父亲,T指向右孩子。(有点难理解,可以具体举个例子跟代码走一遍)
注意:B需为全局指针,让其随着递归传递下去(相当于一个参数传递)
BinTree B=NULL;
bool IsBST ( BinTree T )
{
if(T){
if(!IsBST ( T->Left )) return false;
if(B&&T->Data<B->Data) return false;
B=T;
if(!IsBST ( T->Right )) return false;
}
return true;
}