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

第二十二题:二叉搜索树的后序遍历序列

 

题目描述

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

 

 

思路:递归和非递归的方式

 

          递归:

                    ①找到根节点

                    ②找到第一个比根节点大的结点为分解结点

                    ③判断条件:分界结点到根节点之间的数都比根节点要大

                    ④左右孩子树分而治之

       非递归:

                    利用二叉搜树的特性任意节点的左子树不大于根节点,右子树不小于根节点

                    ①找到根节点

                    ②判断数组前的所有数字都比根节点小或者大

                    ③使用index做为遍历数组的角标

                    ④index < 根节点的位置        说明不符合特性

 

 

具体实现如下图所示:

 

递归版本:

 

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

 

非递归版本:

 

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

 

 

具体实现代码如下:

/**
*〈一句话功能简述〉<br>
*〈二叉搜索树的后序遍历〉
*〈输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。
* 如果是则输出Yes,否则输出No。假设输入的数组的任意两个数字都互不相同。〉
*
* @author 一个鲁肃
* @create 2018/8/14
* @since 1.0.0
*/
public class VerifySquenceOfBST {

    /**
     * 功能描述: <br>
     *〈非递归版本〉
     *
     * @param:sequence
     * @return: boolean
     */
    public boolean verifySquenceOfBST1(int [] sequence) {
        int size = sequence.length;
        //代码的鲁棒性
        if (size == 0){
            return false;
        }
        //定义指针变量
        int i = 0;
        while (--size > 0){
            while (sequence[i] < sequence[size]){
                i++;
            }
            while (sequence[i] > sequence[size]){
                i++;
            }
            //特性判断
            if (i < size) {
                return false;
            }
            i = 0;
        }
        return true;
    }

    /**
     * 功能描述: <br>
     *〈递归版本〉
     *  采取分治思想,左子树<根<=右子树
     *     首先找到根节点,二叉树的后序遍历最后一个节点就是根节点
     *     然后从头遍历找到第一个比根节点大的数字,此时分为左子树和右子树,进行分治判断
     *
     * @param:sequence
     * @return: boolean
     */
    public boolean verifySquenceOfBST2(int [] sequence) {
        //代码的鲁棒性
        if (sequence == null || sequence.length == 0){
            return false;
        }
        return judge(sequence,0,sequence.length-1);
    }
    //判断方法  
    public boolean judge(int[] arr,int start,int end){
        //递归的结束条件
        if (start >= end){
            return true;
        }
        //找到第一个比根节点大的结点
        int index = start;
        while (arr[index] < arr[end]){
            index++;
        }
        //该结点往后的结点都比根节点大
        for (int i = index;i < end;i++){
            if (arr[i] < arr[end]){
                return false;
            }
        }
        //分而治之
        return judge(arr,start,index-1) && judge(arr,index,end-1);
    }

}