题目:实现一个函数,检查一棵二叉树是否为二叉查找树。
解法一:二叉树一个非常重要的特点的是它的中序遍历为递增序列,如果中序遍历递增,那么肯定是二叉查找树。中序遍历的结果可以保存在数组里面。
void AddToArray(BinaryTreeNode* pRoot, int* array, int& size)
{
if(pRoot)
{
AddToArray(pRoot->m_pLeft, array, size);
array[size++] = pRoot->m_nValue;
AddToArray(pRoot->m_pRight, array, size);
}
}
bool CheckBST(BinaryTreeNode* pRoot)
{
int num[20];
int size = 0;
AddToArray(pRoot, num, size);
if(size == 0)
return false;
if(size == 1)
return true;
for(int i = 1; i < size-1; ++i)
{
if(num[i] <= num[i-1])
return false;
}
return true;
}
解法二:解法一中每次将当前结点的值与上一个结点的值比较,因此如果保存了上一次结点的值,就能够完成判断,而不必把所有数字都保存起来。
int lastValue = INT_MIN;
bool CheckBST(BinaryTreeNode* pRoot)
{
if(pRoot == NULL)
return true;
if(!CheckBST(pRoot->m_pLeft))
return false;
if(pRoot->m_nValue <= lastValue)
return false;
lastValue = pRoot->m_nValue;
if(!CheckBST(pRoot->m_pRight))
return false;
}
解法三:对于任意结点,所有左边的结点必须小于当前结点,所有右边结点必须大于当前结点,因此可从根结点开始判断,所有结点的值都应该落在一个区间内,自上而下传递区间的最小值和最大值。进入左子树时,更新最大值,进入右子树,更新最小值。
bool CheckBST(BinaryTreeNode* pRoot, int min, int max)
{
if(pRoot == NULL)
return true;
if(pRoot->m_nValue < min || pRoot->m_nValue > max)
return false;
return CheckBST(pRoot->m_pLeft, min, pRoot->m_nValue) && CheckBST(pRoot->m_pRight, pRoot->m_nValue, max);
}
bool CheckBST(BinaryTreeNode* pRoot)
{
return CheckBST(pRoot, INT_MIN, INT_MAX);
}