来自剑指offer面试题24:二叉搜索树的后序遍历序列
思路:在后序遍历序列中,最后一个数字是树的根节点的值。数组中前面的数字可以分为两部分:第一部分是左子树节点的值。他们都比根节点的值要小;第二部分是右子树的值,他们都比根节点的值都要大。
接下来我们可以用同样的方法确定与数组每一部分对应的子树的结构。这其实是一个递归的过程。
下面是代码:
/************************************************************************/
/* 输入一个数组,判断该数组是不是某二叉搜索树的后续遍历结果,如果是,返回true 剑指offer,面试题24 */
/************************************************************************/
bool SequenceIsPostOrderOfBST(int* arrSequence, int nLength){
if (arrSequence == NULL || nLength <= 0)
{
return false;
}
int nRoot = arrSequence[nLength - 1];//根节点
int i;
for (i = 0; i < nLength - 1; i++) //得到右子树的左边界
{
if (arrSequence[i]>nRoot)
{
break;
}
}
for (int j = i; j < nLength - 1; j++) //判断右子树当中是否有小于根节点的节点
{
if (arrSequence[i]<nRoot)
{
return false;
}
}
//判断左子树是不是二叉搜索树
bool bLeftIsBST = true;
if (i>0)//有左子树
{
bLeftIsBST = SequenceIsPostOrderOfBST(arrSequence, i);
}
//判断右子树是不是二叉搜索树
bool bRightIsBST = true;
if (i < nLength - 1) //有右子树
{
bRightIsBST = SequenceIsPostOrderOfBST(arrSequence + i, nLength - i - 1);
}
return (bLeftIsBST&&bRightIsBST);//左右都是二叉搜索树才算成功
}
举一反三:如果需要判断一个序列是不是一棵二叉搜索树的前序遍历序列,原理也是一样的,只不过此时根节点是数组的第一个值,然后再把第一个值后面的分成左右子树,执行递归即可,下面是代码:
/************************************************************************/
/* 输入一个数组,判断该数组是不是某二叉搜索树的前续遍历结果,如果是,返回true*/
/************************************************************************/
bool SequenceIsPreOrderOfBST(int* arrSequence, int nLength){
if (arrSequence == NULL || nLength <= 0)
{
return false;
}
int nRoot = arrSequence[0];//第一个为根节点
int i = 1;
for (; i < nLength; i++) //得到右子树的左边界
{
if (arrSequence[i]>nRoot)
{
break;
}
}
int j = i;
for (; j < nLength; j++)//判断右子树是不是有小于根节点的
{
if (arrSequence[j]<nRoot)
{
return false;
}
}
bool bLeftIsBST = true;
if (i>1)
{
bLeftIsBST = SequenceIsPreOrderOfBST(arrSequence + 1, i - 1);
}
bool bRightIsBST = true;
if (i < nLength)
{
bRightIsBST = SequenceIsPreOrderOfBST(arrSequence + i, nLength - i);
}
return (bLeftIsBST&&bRightIsBST);
}
如果要判断一个序列是不是一棵搜索二叉树的中序遍历序列,那更好办:从第二个数到倒数第二个数,如果前面的数比它小且后面的数比它大,那就是中序遍历序列!下面是代码:
/************************************************************************/
/*输入一个数组,判断该数组是不是某二叉搜索树的中遍历结果,如果是,返回true*/
/************************************************************************/
bool SequenceIsInOrderOfBST(int*arrSequence, int nLength){
if (arrSequence == NULL || nLength <= 0)
{
return false;
}
int i;
for (i = 1; i<nLength - 1; i++) //从第二个到倒数第二个,前面的数比它小,后面的数比它大,就是中序遍历!
{
if (!(arrSequence[i]>arrSequence[i - 1] && arrSequence[i] < arrSequence[i + 1]))
break;
}
if (i == nLength - 1)//达到了最后,说明是中序遍历序列
{
return true;
}
return false;
}
我们使用如下搜索二叉树进行测试:
测试代码如下:
int main(){
cout << "输入一个数组,判断该数组是不是某二叉搜索树的先序遍历结果,如果是,返回true:" << endl;
int arayPreOrder3[7] = { 8, 6, 5, 7, 10, 9, 11 };
cout << SequenceIsPreOrderOfBST(arayPreOrder3, 7) << endl;
cout << "输入一个数组,判断该数组是不是某二叉搜索树的后序遍历结果,如果是,返回true:" << endl;
int arayPostOrder3[7] = { 5, 7, 6, 9, 11, 10, 8 };
cout << SequenceIsPostOrderOfBST(arayPreOrder3, 7) << endl;
cout << "输入一个数组,判断该数组是不是某二叉搜索树的中序遍历结果,如果是,返回true:" << endl;
int arayInOrder3[7] = { 5, 7, 7, 8, 9, 10, 11 };
cout << SequenceIsInOrderOfBST(arayInOrder3, 7) << endl;
cout << "输入一个数组,判断该数组是不是某二叉搜索树的中序遍历结果,如果是,返回true:" << endl;
int arayInOrder4[7] = { 5, 6, 7, 8, 9, 10, 11 };
cout << SequenceIsInOrderOfBST(arayInOrder4, 7) << endl;
return 0;
}
下面是输出结果: