判断二叉查找树的三种方法

题目

实现一个函数,判断一棵二叉树是否为二叉查找树。

分析

我们知道一棵二叉查找树的中序遍历序列是有序的,所以只需求出中序遍历结果,再依次判断该序列是否有序即可。 但是上述方法需要额外线程空间保存遍历结果,在此可以省去该空间开销,只需一个变量保存访问当前节点时上一节点的值即可。 本文还提供了另一种方法,基于left<=current<right的特性上。

代码

/*
题目描述

请实现一个函数,检查一棵二叉树是否为二叉查找树。
给定树的根结点指针TreeNode* root,请返回一个bool,代表该树是否为二叉查找树。
*/

#include <iostream>
#include <cstdlib>
#include <vector>
#include <queue>

using namespace std;

/*二叉树节点数据结构*/
struct TreeNode {
	int val;
	struct TreeNode *left;
	struct TreeNode *right;
	TreeNode(int x) :
		val(x), left(NULL), right(NULL) {
	}
};

const int flag = INT_MAX;
TreeNode *generateTree(vector<int> &nums)
{
	if (nums.empty())
		return NULL;

	TreeNode *root = new TreeNode(nums[0]);
	queue<TreeNode *> que;
	que.push(root);
	//求出所给元素个数,对应二叉查找树节点个数
	int size = nums.size();
	for (int i = 1; i < size; i += 2)
	{
		//处理队首节点的左右子树
		TreeNode *tmp = que.front();
		TreeNode *left = NULL, *right = NULL;
		//定义非空左子树
		if (nums[i] != flag)
		{
			left = new TreeNode(nums[i]);
			que.push(left);
		}

		//定义非空右子树
		if (i + 1 < size && nums[i + 1] != flag)
		{
			right = new TreeNode(nums[i + 1]);
			que.push(right);
		}

		tmp->left = left;
		tmp->right = right;
		//弹出当前处理的节点
		que.pop();
	}
	return root;
}

class Checker {
public:

	/*方法一,将中序遍历结果保存到数组 T(n)=O(n) S(n)=O(n)*/
	void inOrder(TreeNode *root,vector<int> &v)
	{
		if (root == NULL)
			return;
		inOrder(root->left, v);
		v.push_back(root->val);
		inOrder(root->right, v);
	}

	bool checkBST1(TreeNode* root)
	{
		vector<int> ret;
		inOrder(root, ret);
		for (auto i = ret.begin()+1; i != ret.end(); ++i)
		{
			if (*i < *(i - 1))
				return false;
		}
		return true;
	}

	/*方法二、省掉线性空间,保存遍历的最后一个节点*/
	int lastVal = INT_MIN;
	bool checkBST2(TreeNode* root) {
		// write code here
		if (!root)
			return true;

		/*递归检查左子树*/
		if (!checkBST2(root->left))
			return false;

		/*比较当前节点,并更新已遍历节点最后的值*/
		if (root->val <= lastVal)
			return false;
		lastVal = root->val;

		/*递归检查右子树*/
		if (!checkBST2(root->right))
			return false;
		return true;
	}

	/*方法三,最大最小值法*/
	bool checkBST3(TreeNode* root) {
		// write code here
		if (!root)
			return true;
		return checkBST3(root, INT_MAX, INT_MIN);
	}
	bool checkBST3(TreeNode *root, int maxVal, int minVal)
	{
		if (!root)
			return true;
		if (root->val < minVal || root->val >= maxVal)
			return false;
		if (!checkBST3(root->left, root->val, minVal) || !checkBST3(root->right, maxVal, root->val))
			return false;
		return true;
	}
};

int main()
{
	vector<int> v = { 7, 6, flag, 4, flag, 2, 5, 8, 3, flag, flag, flag, flag, flag, flag };
	TreeNode *root = generateTree(v);

	Checker c;
	bool ret = c.checkBST1(root);

	cout << ret << endl;

	ret = c.checkBST2(root);

	cout << ret << endl;

	ret = c.checkBST3(root);

	cout << ret << endl;

	system("pause");
	return 0;
}

    原文作者:二叉查找树
    原文地址: https://blog.csdn.net/fly_yr/article/details/52172839
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞