数据结构和算法经典100题-第9题

在这里说明一下第6题和第8题是智力题,考察数据结构和算法的知识不多。这里就不给出题目和解题思路了。

第9题 题目

判断整数序列是不是二元查找树的后序遍历结果
题目:输入一个整数数组,判断该数组是不是某二元查找树的后序遍历的结果。
如果是返回true,否则返回false。
例如输入5、7、6、9、11、10、8,由于这一整数序列是如下树的后序遍历结果:
8
/ \
6 10
/ \ / \
5 7 9 11
因此返回true。
如果输入7、4、6、5,没有哪棵树的后序遍历的结果是这个序列,因此返回false。


题目分析:
从本节开始,题目分析部分将详细的介绍考察的数据结构的基础知识和做题的思路。
首先我们看下题目中出现了二叉查找树。
二叉查找树ADT的定义是:二叉树的任意结点n1的左子树上的结点值必须小于n1的值,右子树上的结点的值必须大于n1的值。
题目中要求我们判断一个整数数组是否是某二叉查找树后序遍历的结果。从正反两个方向思考这个问题。
正向的思路是我们得知道二叉查找树后序遍历的结果是什么?然后根据特点找到二叉查找树后序遍历的冲要条件。
反向思路就是将整数序列构造成一棵二叉查找树,然后后序遍历二叉查找树,看看后序遍历的结果是否与输入整数序列相等。

后序遍历二叉查找树有什么特点呢?不难发现:后序遍历二叉树的生成序列的最后一个值,一定是ADT的根。
我们通过ADT的根,也就是最后的一个值将整数序列划分。
划分的条件是第一个出现比根值大的值之前的整数序列为左子树,然后判断划分后的由子树是否都比根小。如果是则递归判断左右子树。从而判断输入整数序列是否是二叉查找树后序遍历的结果。解决问题。

我们看一下代码实现的算法:

#include <iostream>

#include "9th.h"

using namespace std;

bool judgePostSqu(int* squ,int beg,int end)
{
#define RETURN_FALSE return false
#define RETURN_TRUE return true
    if (beg == end || (end - beg) <=1 ) {
        RETURN_TRUE;
    }
    int i = beg;
    int root = squ[end];

    /* 划分序列 */
    for (; i <= end; i++) {
        if (squ[i] > root) {
            break;
        }
    }

    int leftBeg = beg;
    int leftEnd = i - 1;
    int rightBeg = i;
    int rightEnd = end -1;

    /* 检查右子树 */
    for (; i <= end; i++) {
        if (squ[i] < root) {
            RETURN_FALSE;
        }
    }

    /* 递归调用其左、右子树 */
    bool ret = judgePostSqu(squ, leftBeg, leftEnd);
    if (false == ret) {
        RETURN_FALSE;
    }

    ret = judgePostSqu(squ, rightBeg, rightEnd);
    if (false == ret) {
        RETURN_FALSE;
    }

    RETURN_TRUE;
}

头文件:

#ifndef ___00_alg_tests___th__
#define ___00_alg_tests___th__

#include <stdio.h>


int test_9();


#endif /* defined(___00_alg_tests___th__) */

测试程序:

int test_9() {
    bool ret = false;
    int inputArray_0[] = {7,4,6,5};

    int inputArray_1[] = {5,7,6,9,11,10,8};

    ret=judgePostSqu(inputArray_0, 0, 3);
    if (ret) {
        cout<<"输入序列inputArray_0是二叉查找树后序遍历结果"<<endl;
    } else {
        cout<<"输入序列inputArray_0不是二叉查找树后序遍历结果"<<endl;
    }

    ret=judgePostSqu(inputArray_1, 0, 6);
    if (ret) {
        cout<<"输入序列inputArray_1是二叉查找树后序遍历结果"<<endl;
    } else {
        cout<<"输入序列inputArray_1不是二叉查找树后序遍历结果"<<endl;
    }

    return 0;
}
#include "9th.h"

int main(int argc, const char * argv[]) {

    //test_1();
    //test_2();
    //test_3();
    //test_4();
    //maxHeap_test();
    //test_5_1();
//    test_7();
    test_9();

    return 0;
}

测试程序屏幕的打印输出:

输入序列inputArray_0不是二叉查找树后序遍历结果
输入序列inputArray_1是二叉查找树后序遍历结果
Program ended with exit code: 0

路漫漫其修远兮,吾将上下而…

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值