zoukankan      html  css  js  c++  java
  • 二叉堆

    最大堆:

    最大堆的任何一个父节点的值,都大于或等于它左孩子或右孩子节点的值

    最小堆:

    任何一个父节点的值都小于或等于它左孩子或右孩子节点的值
    二叉堆的根节点叫做堆顶
    最大堆和最小堆的特点决定了,最大堆的堆顶是整个堆中的最大元素;
    最小堆的堆顶是整个堆中的最小元素

    二叉堆的自我调整

    就是把一个不符合堆性质的完全二叉树,调整成一个堆
    有如下几种操作:
    1.插入节点:上浮(插入位置是完全二叉树的最后一个位置,也就是最新的一个叶子节点(叶子节点插入从左到右))
    2.删除节点:下沉(删出是处于堆顶的节点,然后把堆的最后一个节点临时补到原本堆顶的位置,让暂时处于堆顶位置的节点与左右孩子节点进行比较)
    3.构建二叉堆:本质是让所有非叶子节点依次"下沉"(非叶子节点:有孩子节点的节点;相对的,叶子节点:没有孩子节点的节点)
    如果该节点大于它的左孩子、右孩子节点中最小的一个,则该节点下沉。

    时间复杂度

    堆的插入和删除操作,时间复杂度是O(logn),这两个操作都是在单一节点上实现"上浮"或下沉,这两个操作的平均交换次数都是堆高度的一半
    而构建堆是所有非叶子节点依次"下沉",时间复杂度是O(n),而不是O(nlogn)

    二叉堆用数组来表示

    二叉堆虽然是完全二叉树,但它的存储方式并不是链式存储,而是顺序存储。获句话说,二叉堆的所有节点都存储在数组中。
    在数组中没有左指针和右指针,可以依靠数组下标来计算
    假设父节点的下标是parent,那么它的左孩子下标就是2parent+1;右孩子的下标就是2parent+2.

    下方展示的代码其实我看不懂

    
    
    def up_adjust(array=[]):
        """
        二叉堆的尾节点上浮操作
    
        :param array: 原数组
        
        """
        child_index = len(array) - 1
        parent_index = (child_index - 1) // 2
        # temp保存插入的叶子节点值,用于最后的赋值
        temp = array[child_index]
        while child_index > 0 and temp < array[parent_index]:
            # 无需真正交换,单向赋值即可
            array[child_index] = array[parent_index]
            child_index = parent_index
            parent_index = (parent_index - 1) // 2
        array[child_index] = temp
    
    '''
    
    '''
    def down_adjust(parent_index, length, array=[]):
        """
        二叉堆的节点下沉操作
        :param parent_index: 待下沉的节点下标
        :param length: 堆的长度范围
        :param array: 原数组
        """
        # temp保存父节点值,用于最后的赋值
        temp = array[parent_index]
        child_index = 2 * parent_index + 1
        while child_index < length:
            # 如果有右孩子,且右孩子小于左孩子的值,则定位到右孩子
            if child_index + 1 < length and array[child_index + 1] < array[child_index]:
                child_index += 1
            # 如果父节点小于任何一个孩子的值,直接跳出
            if temp <= array[child_index]:
                break
            # 无需真正交换,单向赋值即可
            array[parent_index] = array[child_index]
            parent_index = child_index
            child_index = 2 * child_index + 1
        array[parent_index] = temp
    
    
    def build_heap(array=[]):
        """
        二叉堆的构建操作
        :param array: 原数组
        """
        # 从最后一个非叶子节点开始,依次下沉调整
        for i in range((len(array)-2) // 2, -1, -1):
            down_adjust(i, len(array), array)
    
    
    my_array = list([1, 3, 2, 6, 5, 7, 8, 9, 10, 0])
    up_adjust(my_array)
    print(my_array)
    my_array = list([7, 1, 3, 10, 5, 2, 8, 9, 6])
    build_heap(my_array)
    print(my_array)
    
    
    努力拼搏吧,不要害怕,不要去规划,不要迷茫。但你一定要在路上一直的走下去,尽管可能停滞不前,但也要走。
  • 相关阅读:
    Java精度计算与舍入
    java--序列化及其算法透析
    java--序列化及其算法透析
    python脚本删除文件与目录的命令
    合成大西瓜CocosCreator开发源码(可跨平台构建:小程序、android...)
    如何使用C++做个简单推箱子游戏
    unityZXing二维码的生成与扫描
    第八届“图灵杯”NEUQ-ACM程序设计竞赛个人赛(同步赛)全题解
    unityZXing二维码的生成与扫描
    35岁的程序员:第20章,解脱
  • 原文地址:https://www.cnblogs.com/wkhzwmr/p/15248554.html
Copyright © 2011-2022 走看看