3.12python如何在二叉排序树中找出第一个大于中间值的结点

题目描述:

对于一棵二叉排序树,令f=(最大值+最小值)/2,设计一个算法,找出距离 f 值最近、大于 f 值的结点。例如,下图所给定的二叉排序树中,最大值为7,最小值为1,所以 f=(1+7)/2=4,那么在这棵二叉树中,距离结点4最近且大于4的结点为5。
在这里插入图片描述

思路:

首先需要找出二叉排序树中的最大值和最小值。由于二叉排序树的特点是,对于任意一个结点,它的左子树上所有结点的值都小于这个结点的值,它的右子树上所有结点的值都大于这个结点的值。所以,在二叉排序树中,最小值一定是最左下的结点,最大值一定是最右下的结点。根据最大值与最小值很容易求出 f 的值。接下来对二叉树进行中序遍历。如果当前结点的值小于 f,那么在这个结点的右子树( 左小右大 )中接着遍历,否则遍历这个结点的左子树。

代码实现:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# @Time    : 2020/1/26 11:40
# @Author  : buu
# @Software: PyCharm
# @Blog    :https://blog.csdn.net/weixin_44321080
class BiTNode:
    def __init__(self):
        self.data = None
        self.lchild = None
        self.rchild = None


def getMin(root):
    """
    查找值最小的结点
    :param root: 二叉树的根结点
    :return: 最小值的结点
    """
    if root == None:
        return root
    while root.lchild != None:
        root = root.lchild
    return root


def getMax(root):
    """
    查找值最大的结点
    :param root: 二叉树的根结点
    :return: 最大值的结点
    """
    if root == None:
        return root
    while root.rchild != None:
        root = root.rchild
    return root


def array2treee(arr, start, end):
    """
    把有序数组转换为二叉树
    :param arr:数组
    :param start:数组起点
    :param end:数组终点
    :return:
    """
    root = None
    if end >= start:
        root = BiTNode()
        mid = (start + end + 1) // 2
        root.data = arr[mid]  # 树的根节点为数组中间的元素
        # print(root.data,end=' ')
        root.lchild = array2treee(arr, start, mid - 1)  # 递归地构建左子树
        root.rchild = array2treee(arr, mid + 1, end)  # 递归地构建右子树
    else:
        root = None
    return root


def getNode(root):
    if root == None:
        return root
    minNode = getMin(root)
    maxNode = getMax(root)
    midVal = (minNode.data + maxNode.data) / 2
    result = None
    while root != None:
        if root.data <= midVal:  # 当前值的结点不大于中间值,则在当前结点的右子树上查找
            root = root.rchild
        else:  # 若当前结点的值大于中间值,则在当前结点的左子树上查找
            result = root # 先记录下第一个大于中间值的结点,
            # 因为左子树小于当前结点root的值,所以继续向左寻找
            root = root.lchild # 直至找到第一个(即距离中间值最近)大于中间值的结点
    return result


if __name__ == '__main__':
    arr = [1, 2, 3, 4, 5, 6, 7]
    root = array2treee(arr, 0, len(arr) - 1)
    print('find val: ', end='')
    print(getNode(root).data)

结果:
在这里插入图片描述
算法性能分析:
这种方法查找最大结点与最小结点的时间复杂度为O(h),h为树的高度。对于有 n 个结点的二叉排序树,最大的高度为O(n),最小的高度为O(logn),所以在查找满足条件的结点的时候,时间复杂度为O(h)。综上,此方法的时间复杂度在最好的情况下是O(logn),最坏的情况下是O(n);

end

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

猜你喜欢

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