题目:输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则输出1否则输出-1。假设输入的数组的任意两个数字都互不相同
例如输入数组a[] = {5,7,6,9,11,10,8}; 返回1。
在后续遍历中,最后一个数字是树的根节点的值。数组中前面的数字可以划分为两部分:第一部分为左子树节点,他们的值都比根节点小;第二部分为右子树节点,他们的值都比根节点大。
如栗子中 数组a[] = {5,7,6,9,11,10,8};,后续遍历最后一个数字8就是根节点的值,在这个数组中,前三个数字的值分别为5,6,7, 都比根节点的值 8 小,故为8 的左子树节点。后三个数字分别为9、10、11,都比8大,故为8的右子树。此时左右子树又可以根据刚才的方法找出根节点,一次类推来判断。
于是我们很容易想到了递归,是滴,天然的递归条件。
来看看代码吧
int CheckArryIsAfterOrder(Datatype *a,size_t len) //判断一个序列是否是二叉树的后序遍历
{
size_t tmp = len-1;
size_t i = 0,j = 0;
int right = 0;
for (i=0; i<len-1; i++) //找出第一个左子树
{
if (a[i] > a[tmp])
break;
}
for (j=i;j<len-1; j++) //判断右子树是否满足。
{
if (a[j] < a[tmp])
return -1;
}
right = 1; //此时右子树一定满足搜索二叉树的后序遍历
if (i>0)
CheckArryIsAfterOrder(a,i);
return 1; //此时左右子树都满足
}
测试案例及运行结果:
void TestOffer()
{
Datatype a1[] = {5,7,6,9,11,10,8};
Datatype a2[] = {57,4,6,5};
size_t len1 = sizeof(a1)/sizeof(a1[0]);
size_t len2 = sizeof(a2)/sizeof(a2[0]);
printf("%d \n",CheckArryIsAfterOrder(a1,len1));
printf("%d \n",CheckArryIsAfterOrder(a2,len2));
}