判断二叉搜索树的严谨递归方法
树类的定义与主函数
class tree {
public:
int value;
class tree* left;
class tree* right;
tree(int value=0, tree* left=nullptr, tree* right=nullptr
:value(value), left(left), right(right){
}
};
int main()
{
string s1("4_#_#_");
string s2("2_1_#_#_3_#_#_");
string s3("6_5_#_#_7_#_#_");
tree* t1 = PDSL(s1);
tree* t2 = PDSL(s2);
tree* t3 = PDSL(s3);
t2->left->value = INT_MIN;
t1->left = t2;
t1->right = t3;
pri(t1);
cout << BST(t1);
}
主函数中PDSL反序列化与pri打印二叉树代码省略,下面主要讨论BST的实现
不严谨的一种递归实现
static int maxleft=INT_MIN;
bool BST(tree* t) {
if (t == nullptr)
return true;
if (BST(t->left)!=true) {
return false;
}
if (maxleft >= t->value)
return false;
else
maxleft = t->value;
return BST(t->right);
}
实现原理与不严谨之处
原理:
先判断节点t的左树是否为二叉搜索树,再判断左树最大值是否小于节点t的值,并更新(先序遍历到目前为止)的最大值maxleft(程序刚开始赋值为INT_MIN),再以当前maxleft值继续判断节点t右树是否为二叉搜索树。
不严谨之处:
仅有一种情况该程序判断错误。由程序刚开始时maxleft赋值为INT_MIN,故若:先序遍历的第一个节点值恰为INT_MIN,且该树为二叉搜索树,则由于maxleft并不小于该节点的值,最终运行结果为false
运行结果
由于字符串太长,打印没有对齐。实际上,3是2的右孩子,5、7分别是6的左右孩子。0表示非二叉搜索树
改进后的代码
static int maxleft;
bool BST(tree* t) {
if (t == nullptr)
return true;
static bool isfirst = true;//是否判断先序第一个节点
if (BST(t->left)!=true) {
return false;
}
if (isfirst) {//只在第一次执行
maxleft = t->value;
isfirst = false;
return BST(t->right);
}
if (maxleft >= t->value)
return false;
else
maxleft = t->value;
return BST(t->right);
}
改进的原理
maxleft不需初始化,取而代之的是通过定义一个静态bool变量isfirst,在第一次与非空节点比较时,将值赋给maxleft,从而避免错误发生。
运行结果
改进后的运行结果是正确的,结果为true