二叉搜索树的后序遍历序列

问题

输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则输出Yes,否则输出No。假设输入的数组的任意两个数字都互不相同。

思路

 

以{5,7,6,9,11,10,8}为例,后序遍历结果的最后一个数字8就是根结点的值。在这个数组中,前3个数字5、7和6都比8小,是值为8的结点的左子树结点;后3个数字9、11和10都比8大,是值为8的结点的右子树结点。

我们接下来用同样的方法确定与数组每一部分对应的子树的结构。这其实就是一个递归的过程。对于序列5、7、6,最后一个数字6是左子树的根结点的值。数字5比6小,是值为6的结点的左子结点,而7则是它的右子结点。同样,在序列9、11、10中,最后一个数字10是右子树的根结点,数字9比10小,是值为10的结点的左子结点,而11则是它的右子结点。

我们使用递归的方法,先判断数组的左子树和右子树的位置,然后再判断左子树、右子树是不是二叉搜索树。

public class Solution {
   /**二叉搜索树的性质:
     * 所有左子树的节点小于根节点,所有右子树的节点值大于根节点的值。
     * 算法步骤:
     * 1.后序遍历的最后一个值为root,在前面的数组中找到第一个大于root值的位置。
     * 2.这个位置的前面是root的左子树,右边是右子树。然后左右子树分别进行这个递归操作。
     * 3.其中,如果右边子树中有比root值小的直接返回false
     * @param sequence
     * @return
     */
    public boolean VerifySquenceOfBST(int [] sequence) {
    	if (sequence == null || sequence.length == 0) 
			return false;
    	return IsBST(sequence, 0, sequence.length -1);
    	
    }
    
    public boolean IsBST(int [] sequence, int start, int end) {
    	if(start >= end) 
            //注意这个条件的添加
            // 如果对应要处理的数据只有一个或者已经没
            //有数据要处理(start>end)就返回true
    		return true;
    	int index = start;
    	for (; index < end; index++) {
            //寻找大于root的第一个节点,然后再分左右两部分
			if(sequence[index] > sequence[end])
				break;
		}
        for (int i = index; i < end; i++) {
            //若右子树有小于根节点的值,直接返回false
			if (sequence[i] < sequence[end]) {
				return false;
			}
		}
        return IsBST(sequence, start, index-1) && IsBST(sequence, index, end-1);
	}
    
}
public boolean verifySquenceOfBST(int sequence[]){
	if(sequence == null){
		return false;
	}
	return verifySquenceOfBST1(sequence, 0, sequence.length - 1);
}
 
private boolean verifySquenceOfBST1(int[] sequence, int start, int end) {
	if(start >= end){
		return true;
	}
	int root = sequence[end]; //后序遍历的最后一个结点为根结点
		
	//在二叉搜索树中左子树的结点小于根结点
	int i = 0;
	for(; i < end; ++i){
		if(sequence[i] > root){
			break;
		}
	}
		
	//在二叉搜索树中右子树的结点大于根结点
	int j = i;
	for(; j < end; ++j){
		if(sequence[j] < root){
			return false;
		}
	}
	//判断左子树是不是二叉树
	boolean left = true;
	if(i > start){
		left = verifySquenceOfBST1(sequence, start, i-1);
	}
	//判断右子树是不是二叉树
	boolean right = true;
	if(i < end){
		right = verifySquenceOfBST1(sequence, i, end -1); 
	}
	return (left && right);
}