14 判断给定的二叉排序树后序遍历序列是否合法
2016-01-11 20:45
519 查看
前言
本博文部分图片, 思路来自于剑指offer 或者编程珠玑问题描述
思路
对于这个问题, 书中给出了一种解法思路 : 输入为一个后序遍历的序列, 从这里 我们可以得到序列中最后一个元素为根节点, 又因为该树是二叉排序树, 则表明序列中左子树的每一个结点的key小于等于根节点的key, 右子树的部分每一个结点的key大于等于根节点的key, so 我们是可以根据后序遍历序列大致区分出整棵树的左子树部分, 右子树部分 [不能确定的部分为和根节点关键字相同的结点], 这样就可以根据二叉排序树的性质进行校验了
首先 找到序列中第一个比最后一个key大的元素[索引即为idx], 然后在校验arr[idx] - arr[end-1]之间的数据, 是否都大于arr[end], 如果不全小于arr[end] 则返回false
否则 便通过了初步的筛选, 然后进行递归校验左右子树, 如果左右子树任意一个不符合结点 返回false, 都通过了, 当前后序遍历序列才是正常的二叉排序树后序遍历序列
参考代码
/** * file name : Test07IsBinarySortedTreeEpilogue.java * created at : 2:48:59 PM Jun 7, 2015 * created by 970655147 */ package com.hx.test05; public class Test07IsBinarySortedTreeEpilogue { // 判断给定的序列是否是二叉排序树的后序序列 public static void main(String []args) { // int[] arr = new int[] {5, 7, 1, 9, 11, 10, 8 }; int[] arr = new int[] {6, 11, 19, 27, 17, 37, 48, 38, 32 }; // int[] arr = new int[] {6, 11, 17, 19, 27, 22, 48, 18, 37, 48, 38, 32 }; boolean isLegal = isBinarySortedTreeEpilogue(arr, 0, arr.length-1); Log.log(isLegal); } // 注意 : start, end 包头包尾 // 思路 : 如果只有一个 结点 直接返回true // 否则 从[start, end]找到 第一个大于arr[end]结点的数据的索引first, 然后校验[first, end)的数据 是否都大于end, 如果存在任意一个小于end, 直接返回false // 然后 校验左子树和右子树, 如果左子树的存在结点 递归校验左子树, 如果左子树校验返回false 直接返回false // 然后 校验右子树, 如果左右子树均校验通过 则 返回true public static boolean isBinarySortedTreeEpilogue(int[] arr, int start, int end) { if(arr == null) { return false; } if(start == end) { return true; } int first = findFirstBiggerThan(arr, start, end, arr[end]); // verify the seq since first which is bigger than root; for(int i=first; i<end; i++) { if(arr[i] < arr[end]) { return false; } } boolean isLeftLegal = true, isRightLegal = true; if(first > start) { isLeftLegal = isBinarySortedTreeEpilogue(arr, start, first-1); if(!isLeftLegal) { return false; } } if(first < end) { isRightLegal = isBinarySortedTreeEpilogue(arr, first, end-1); } return isLeftLegal && isRightLegal; } // 注意 : start, end 包头不包尾 // 在[start, end)中 找到第一个大于tar的数据的索引 private static int findFirstBiggerThan(int[] arr, int start, int end, int tar) { for(int i=start; i<end; i++) { if(arr[i] > tar) { return i; } } return end; } }
效果截图
总结
因为二叉排序树 和后序遍历序列的性质很明显, 所以思路应该是不难, 时间复杂度为线性时间复杂度注 : 因为作者的水平有限,必然可能出现一些bug, 所以请大家指出!
相关文章推荐
- java对世界各个时区(TimeZone)的通用转换处理方法(转载)
- java-注解annotation
- java-模拟tomcat服务器
- java-用HttpURLConnection发送Http请求.
- java-WEB中的监听器Lisener
- Android IPC进程间通讯机制
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- 介绍一款信息管理系统的开源框架---jeecg
- 聚类算法之kmeans算法java版本
- java实现 PageRank算法
- PropertyChangeListener简单理解
- c++11 + SDL2 + ffmpeg +OpenAL + java = Android播放器
- 插入排序
- 冒泡排序
- 堆排序
- 快速排序
- 二叉查找树