0.题目
输入一个整数数组,判断该整数数组是不是一颗二叉搜索树的后序遍历。例如,
[1,2,5,6,4]
是一颗二叉搜索树的后序遍历,[1,7,5,2,6,4]
不是二叉搜索树的后序遍历。如果是,返回1,不是返回0。
1.解题思路
- 第一步,确定根结点,对于一颗二叉搜索树的后序遍历,最后一个数一定是二叉搜索树的根。
- 第二步,从头开始找到第一个大于根节点值的值,如果数组中的第一个数就大于根节点的值,说明这棵树是没有左子树的;如果不是数组中的第一个数,则数组中剩余的数为树的右子树,根据性质二叉搜索树的右子树结点的值全部大于根节点的值,我们遍历数组剩下的数组,如果存在小于根节点值得数,说明不是二叉搜索树;如果没有至少可以说明以根结点这颗大的数是二叉搜索树。
- 第三步,对这颗二叉树的左子树进行判断(和上边的方法一样,是一个子问题)。
- 第四部,对这颗二叉树的右子树进行判断(和上边的方法一样,是一个子问题)
3.代码实现
//判断一个序列是否为二叉搜索树的后序遍历(是返回1,不是返回0)
int IsLastOrder(int Order[], int len)
{
if (Order == NULL || len <= 0)
{
return 0;
}
//确定根节点(数组最后一个数)
int root = Order[len - 1];
int i = 0;
//找到第一个大于根结点的值
for (; i < len - 1; i++)
{
if (Order[i] > root)
{
break;
}
}
//现在i为第一个大于root的值得下标
int j = i;
//在右子树中如果存在小于根的值,则必然不是二叉搜索树
for (; j < len - 1; j++)
{
if (Order[j] < root)
{
return 0;
}
}
//递归判断左子树(如果左子树为空,则肯定是后序遍历,所以要初始化为1)
int left = 1;
if (i > 0)
{
//左子树数组的长度为i
left = IsLastOrder(Order, i);
}
//递归判断右子树(如果左子树为空,则肯定是后序遍历,所以要初始化为1)
int right = 1;
if (i < len - 1)
{
//左子树数组的长度为len-i-1(要减去根结点)
right = IsLastOrder(Order + i, len - i - 1);
}
return left&&right;
}
3.扩展(判断给定数组是不是二叉搜索树的前序遍历)
思路方法和后序是一样的,只是将根节点改为数组的第一个元素
int IsPrevOrder(int Order[], int len)
{
if (Order == NULL || len <= 0)
{
return 0;
}
int root = Order[0];
int i = 1;
for (; i < len; i++)
{
if (Order[i] > root)
{
break;
}
}
int j = i;
for (; j < len; j++)
{
if (Order[j] < root)
{
return 0;
}
}
int left = 1;
if (i>1)
{
left = IsPrevOrder(Order, i - 1);
}
int right = 1;
if (i < len - 1)
{
right = IsPrevOrder(Order, len - i);
}
return left&&right;
}