题目
如果输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果,如果是则返回true,如果不是则返回false。假设输入的数组的任意两个数字都互不相同。
分析:在后序遍历得到的序列中,最后一个数字是树的根节点的值,数组中前面的数字可以分为两个部分:第一部分为左子树的节点的值,他们都比根节点的值要小;第二部分是右子树节点的值,他们都比根节点的值大。我们在解决这个问题的时候需要用同样的方法来确定与数组每一部分对应的子树结构,这其实就是一个递归的过程。
代码实现:
package cn.csu.pointoffer;
public class Ponit2OfferTest24 {
/**
* 输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。
* 如果是则返回true。否则返回false。假设输入的数组的任意两个数字都互不相同
*
* @param sequeue 某二叉搜索树的后序遍历的结果
* @return true:该数组是某二叉搜索树的后序遍历的结果。false:不是
*/
public static boolean verifySequenceOfBST(int[] sequeue) {
if(sequeue == null || sequeue.length ==0) {
return false;
}
//调用辅助的方法
return verifySequenceOfBST(sequeue, 0, sequeue.length-1);
}
/**
*
* @param sequue 某二叉搜索树的后序遍历的结果
* @param start 处理的起始位置
* @param end 处理的结束为止
* @return true:该数组是某二叉搜索树的后序遍历的结果。false:不是
*/
public static boolean verifySequenceOfBST(int[] sequue,int start,int end) {
//如果对应要处理的数据只有一个或者已经没有数据要处理(start>end)就返回true
if(start >= end) {
return true;
}
//定义index代表当前处理位置
int index = start;
//从左向右找第一个不大于根结点(sequence[end])的元素的位置
while(index<end -1 && sequue[index] <sequue[end]) {
index++;
}
//如果上面的while循环执行结束,此时的sequeue中下标为[start,index-1]的值都小于根节点。
//这些元素是树的左子树节点
int right = index;
// 接下来要保证[index, end-1]的所有元素都是大于根根点的
// 因为[index, end-1]下标的元素是根结点的右子树
// 从第一个不小于根结点的元素开始,找第一个不大于根结点的元素
while(index <end -1 && sequue[index] > sequue[end]){
index++;
}
//如果上面的条件满足,到while循环结束,此时的index=end-1
// 如果不满足那说明根结点的右子树[index, end-1]中有小于等于根结点的元素,
// 不符合二叉搜索树的定义,返回false
if(index != end -1) {
return false;
}
//递归的判断
return verifySequenceOfBST(sequue, start, right-1)
&& verifySequenceOfBST(sequue, right, end-1);
}
public static void main(String[] args) {
int[] data = {4, 8, 6, 12, 16, 14, 10};
System.out.println("true: " + verifySequenceOfBST(data));
}
}
输出结果:
true: true