程序员面试100题精选(6)

题目:输入一个整数数组,判断该数组是不是某二元查找树的后序遍历序列的结果。如果是,则返回true,否则,返回false。

例如,输入[5,7,6,9,11,10,8]
构造的二叉树为
       8
     /  \
    6    10
   / \   / \
  5   7 9   11
 
输出的结果为true。如果输入为[7,4,6,5],没有那棵树的后序遍历的结果是这个序列,因此返回false。
 
    分析:刚开始看这道题时没有任何的头绪,虽然知道二叉查找树的性质,每个节点的左子树的值都小于等于根节点,有子树的值都大于根节点。看了分析之后才有了头绪,对于后序遍历来说,根节点永远在遍历序列的最后,所以可以从第一个元素开始遍历,直到找到第一个比他大的元素,以此为分界点,若从分解元素到最后的结点之间没有比根节点的值小的元素,则分别对分界点之前和之后的元素序列采用递归的方法进行判断,否则返回false,直到最后一个结点遍历结束,若都符合则返回true。
    因为每次遍历所分元素序列大于3个时,则需要继续递归,若为3个,则将第一个和第二个元素以此与第三个进行比较,看是否符合条件,如果递归的序列中有两个元素,则不管这两个元素的大小关系都返回true,因为两个元素说明该科子树只有一个叶节点,当小于或者大于时只是左子树和右子树那个空的问题,对输入的遍历序列没有任何的影响。
    因为是跟树相关的程序,首先想到使用递归,之前几天一直在看递归的代码,虽然依然没能搞的非常清楚,但越是这样,越要多练习,长期坚持下来,肯定会受到不一样的结果,于是决定写递归代码。最后的完整代码整理如下:
 
 1 //输入一个整数数组,判断该数组是不是某二元查找树的后序遍历的结果。
2 //如果是返回true,否则返回false
3 //分析:对于后序遍历来说,树的根节点位于数组的最后位置,遍历
4
5 #include <iostream>
6 using namespace std;
7 bool isInputPostOrder(int inputArray[ ],int start,int end)
8 {
9 //对于一个函数需要检测其输入条件是否符合事实,在函数内部刚开始的地方进行检测,有利于程序的健壮性
10 if(inputArray&&end>start)
11 {
12 int flag=0;
13 if(end-start == 2)
14 {
15 if((inputArray[start] <=inputArray[end])&&(inputArray[start+1]>inputArray[end]))
16 return true;
17 else
18 return false;
19 }
20 if((end-start == 0)||(end-start==1))
21 return true;
22
23 for(int i=start;i<end;i++)
24 {
25 if(inputArray[i]<inputArray[end])
26 continue;
27 else
28 {
29 flag=i;
30 break;
31 }
32 }
33 return isInputPostOrder(inputArray,start,flag-1)&&isInputPostOrder(inputArray,flag,end-1);
34 }
35 }
36 void main()
37 {
38 int array[]={7,5,11,10,9,14,20,18,15,12};
39 int length=sizeof(array)/sizeof(int);
40
41 bool finalResult=false;
42 finalResult=isInputPostOrder(array,0,length-1);
43 }
posted @ 2012-02-04 10:21  蓝色地中海  阅读(437)  评论(0编辑  收藏  举报