二叉堆

最大堆:

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

最小堆:

任何一个父节点的值都小于或等于它左孩子或右孩子节点的值

二叉堆的特性

二叉堆的根节点叫做堆顶
最大堆和最小堆的特点决定了,最大堆的堆顶是整个堆中的最大元素;
最小堆的堆顶是整个堆中的最小元素

二叉堆的自我调整

就是把一个不符合堆性质的完全二叉树,调整成一个堆
有如下几种操作:
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)

posted @ 2021-09-09 19:45  索匣  阅读(85)  评论(0编辑  收藏  举报