验证二叉搜索树

此生再无相见时 提交于 2020-02-07 07:54:04

题目

Alt

思路

自己的思路

错误思路

首先我们先分析一下题目,二叉搜索树就是左子树所有的节点都比根节点的关键值小,右子树所有节点的关键值都比根节点关键值大,一开始自己的思路就是利用递归,比较左子树根节点的关键值和根节点的关键值,和比较右子树根节点的关键值和根节点的关键值,然后再分别递归的判断左子树和右子树。相关代码如下:

bool isValidBST(TreeNode* root) {
		//下式只能判断出任意节点的左子树根节点都小于该节点,右子树的根节点都大于该节点,并不能得出其就是二叉搜索树
		if (root == NULL) {
			return true;
		}
		TreeNode* T = root;
		bool left=true, right=true;
		if ((!T->left && T->val < T->left->val) || (!T->right && T->right->val < T->val))
			return false;
		left = isValidBST(T->left);
		right = isValidBST(T->right);
		return left*right;
}

上述思路不能判断一棵二叉树是否就是二叉搜索树,因为不能保证满足条件左子树所有节点的关键值都小于根节点关键值,右子树所有节点关键值都大于根节点关键值,只能得出任意节点的关键值都大于其左儿子和右儿子的关键值。

正确思路(但是不是最优方案)

我们每次都寻找一个节点的左子树(若存在)的最大关键值节点(很容易找到)和右子树最小关键值节点,然后比较该节点关键值和这两个节点关键值大小,如果不满足大小关系,则返回false,否则递归判断左子树和右子树,相关代码如下:

bool isValidBST(TreeNode* root) {
		//代码能解决问题,不过不够简洁
		if (root == NULL)
			return true;
		if (!root->left && !root->right)/
			return true;
		TreeNode* L=root->left, *R=root->right;
		bool left, right;
		while (R&&R->left)/寻找右子树最小关键值节点
			R = R->left;
		while (L&&L->right)//寻找左子树最大关键值节点
			L = L->right;
		if ((R && root->val >= R->val) || (L && root->val <= L->val))
			return false;
		left = isValidBST(root->left);
		right = isValidBST(root->right);
		return left * right;
}

参考思路

第一种思路就是递归和中序遍历相结合,我们知道,中序遍历的顺序是:左子树——根节点——右子树,那么这样的顺序是一种递增的关系,那么我们只要判断是否存在不满足这种递增关系的节点就能得出结果

  • 设置一个指针,这个指针的作用就是用来作判断作用(为什么要采用指针而不直接用int类型的变量?因为如果设置成int变量,当节点值为边界值的时候(即为INT_MIN或者INT_MAX),这样int类型变量的初值就等于此时节点的关键值,就破坏了二叉搜索树的判断
  • 首先先判断左子树是否满足二叉搜索树的条件,也是采用递归
  • 然后再判断左子树根节点和根节点的大小关系,若不满足返回false
  • 更新指针值
  • 再递归判断右子树是否满足二叉搜索树的条件
    相关代码如下:
bool isValidBST(TreeNode* root) {
//递归和中序遍历的结合
		/*if (root == NULL)
			return true;
		if (!isValidBST(root->left))
			return false;
		if (last && *last >= root->val)
			return false;
		last = &root->val;
		if (!isValidBST(root->right))
			return false;	
		return true;*/
}

另外一个就是只采用中序遍历的迭代算法,也是利用中序遍历的访问顺序:左子树——根节点——右子树
相关代码如下:

bool isValidBST(TreeNode* root) {
//中序遍历
		if (root == NULL)
			return true;
		stack<TreeNode*> s;
		while (root || !s.empty()) {
			while (root) {
				s.push(root);
				root = root->left;
			}
			root = s.top();
			s.pop(); 
			if (last && *last >= root->val)
				return false;
			last = &root->val;
			root = root->right;
		}
		return true;
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!