3.7python判断一个数组是否是二元查找树的后序遍历的序列

题目描述:

输入一个整数数组,判断该数组是否是某二元查找树的后序遍历的结果。如果是,则返回True,否则返回 False。例如数组 [1,3,2,5,7,6,4]就是下图中二叉树的后序遍历序列。
在这里插入图片描述

思路:

二元查找树的特点是:对于任意一个结点,它的左子树上所有结点的值都小于这个结点的值,它的右子树上的所有结点的值都大于这个结点的值。
根据它的这个特点以及二元查找树后序遍历的特点,可以看出,这个序列的最后一个元素一定是树的根结点(上图中的结点4),然后在数组中找到第一个大于根结点4的值5,那么结点5之前的序列(1,3,2)对应的结点一定位于结点4的左子树上,结点5(包含这个结点)后面的序列一定位于结点4的右子树上(也就是说结点5后面的所有值都应该大于或等于4)。对于结点4的左子树遍历的序列{1,3,2}以及右子树的遍历序列{5,7,6}可以采用同样的方法来分析,所以可以用递归的方法。

算法性能分析:

此方法只对数组进行了一次遍历,所以时间复杂度为O(n);

代码实现:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# @Time    : 2020/1/24 11:32
# @Author  : buu
# @Software: PyCharm
# @Blog    :https://blog.csdn.net/weixin_44321080
def isAfterOrder(arr, start, end):
    """
    判断一个数组是否是二元查找树的后序遍历序列
    算法:
    首先找到树的根结点,然后在数组中找到第一个大于根结点的数据,
    然后判断该数据之前的所有数据是否小于根结点的值,
    该数据之后的所有数据是否大于根结点的值。
    对子数组递归判断。
    :param arr: 数组
    :param start:
    :param end:
    :return: True or False
    """
    if arr == None:
        return False
    root = arr[end]  # 数组的最后一个结点必定是根结点
    i = start
    while i < end:  # 找到仪狄格大于root的值,那么前面所有结点都位于root的左子树上
        if (arr[i] > root):
            break
        i += 1
    j = i  # 如果是后序遍历的序列,那么从i开始的所有值都应该大于根结点root的值
    while j < end:
        if arr[j] < root:
            return False
        j += 1
    left_IsAfterOrder = True
    right_IsAfterOrder = True
    if i > start:  # 判断小于root值的序列是否是某一二元查找树的后序遍历
        left_IsAfterOrder = isAfterOrder(arr, start, i - 1)
    if j < end:  # 判断大于root值的序列是否是某一二元查找树的后序遍历
        right_IsAfterOrder = isAfterOrder(arr, i, end)
    return left_IsAfterOrder and right_IsAfterOrder


if __name__ == '__main__':
    arr = [1, 3, 2, 5, 7, 6, 4]
    result = isAfterOrder(arr, 0, len(arr) - 1)
    i = 0
    while i < len(arr):
        print(arr[i], end=' ')
        i += 1
    if result:
        print('\nyes!')
    else:
        print('\nno!')

结果:
在这里插入图片描述

end

发布了76 篇原创文章 · 获赞 2 · 访问量 2556

猜你喜欢

转载自blog.csdn.net/weixin_44321080/article/details/104079793