C语言强化(八)判断序列是不是二叉查找树的后序遍历结果
前面聊了一系列关于链表相交的问题,本篇博文,让我们通过一道简单的判断题,复习复习数组和二叉树。
通过这道题,你可以掌握
- 二叉查找树的规律
- 后序遍历的特点
- 递归的使用
题目
输入一个整数数组,判断该数组是不是某二元查找树的后序遍历的结果。
如果是返回 true,否则返回 false。
如果是返回 true,否则返回 false。
例如输入 5、7、6、9、11、10、8,由于这一整数序列是如下树的后序遍历结果:
因此返回 true。
如果输入 7、4、6、5,没有哪棵树的后序遍历的结果是这个序列,因此返回 false。
如果输入 7、4、6、5,没有哪棵树的后序遍历的结果是这个序列,因此返回 false。
看到二元查找树(or二叉查找树),第一反应,比根结点大的数在右边,比根结点小的数在左边
接着看到后序查找,第一反应,最后遍历到的数是根结点
做到这两点,此题就没什么难度了,就当过个编程瘾。当然在一些难度较大的题目,光是发现这两个规律是不够的。
思路
因为是后续遍历,那么最后遍历到的数是根结点。
又因为是二叉查找树,所以比根结点大的数在右边,比根结点小的数在左边,
左边的数遍历比右边的较快被遍历到!
所以必须满足比根结点大的数中最小角标 比 比根结点小的数中最大角标 要大!
对左右子数组同样使用上面的思路进行递归判断!
如果数组的长度小于等于3,则不需判断,肯定满足
又因为是二叉查找树,所以比根结点大的数在右边,比根结点小的数在左边,
左边的数遍历比右边的较快被遍历到!
所以必须满足比根结点大的数中最小角标 比 比根结点小的数中最大角标 要大!
对左右子数组同样使用上面的思路进行递归判断!
如果数组的长度小于等于3,则不需判断,肯定满足
源代码
#include <stdio.h> #include<stdlib.h> #include <iostream> #include<sstream> #include <vector> using namespace std; /** 题目: 输入一个整数数组,判断该数组是不是某二元查找树的后序遍历的结果。 如果是返回 true,否则返回 false。 思路 如果是后续遍历,那么最后遍历到的数是根结点。 又因为是二叉查找树,所以比根结点大的数在右边,比根结点小的数在左边, 左边的数遍历比右边的较快被遍历到! 所以必须满足比根结点大的数中最小角标 比 比根结点小的数中最大角标 要大! 对子数组同样使用上面的思路进行递归判断! 如果子数组的长度小于等于3,则不需判断,肯定满足 */ /** ifBTreeHouXu vt 给一个vector数组,判断是否是后序遍历结果 */ bool ifBTreeHouXu(vector<int> vt){ if(vt.size()<=0||NULL== &vt) return false; if(vt.size()>3){//如果子数组的长度小于等于3,则不需判断,肯定满足 int root = vt[vt.size()-1];//获取根结点值 bool flag = true; vt.pop_back();//剔除根结点 vector<int> vt_small;//小于根结点的数组 vector<int> vt_big;//大于根结点的数组 //遍历 for(int i = 0;i<vt.size();i++){ //如果遍历到一个数比根结点大,则把flag置为false //下面如果再遍历到一个数比根结点小,则说明该数组不是后序遍历结果 if(flag&&vt[i]>root) flag=false; else if(flag&&vt[i]<root) vt_small.push_back(vt[i]); else if(!flag&&vt[i]>root) vt_big.push_back(vt[i]); else return false;//此数组不是后序遍历结果 } return ifBTreeHouXu(vt_small)&&ifBTreeHouXu(vt_big); } return true; } vector<int> vt_test; void initTure(){ vt_test.push_back(5); vt_test.push_back(7); vt_test.push_back(6); vt_test.push_back(9); vt_test.push_back(11); vt_test.push_back(10); vt_test.push_back(8); } void initFalse(){ vt_test.push_back(7); vt_test.push_back(4); vt_test.push_back(6); vt_test.push_back(5); } void main() { initTure(); //initFalse(); if(ifBTreeHouXu(vt_test)) cout<<"是后序遍历结果"<<endl; else cout<<"【不】是后序遍历结果"<<endl; system("pause"); }
运行图
总结:
二元查找树,第一反应,比根结点大的数在右边,比根结点小的数在左边
后序查找,第一反应,最后遍历到的数是根结点