📜  建立堆的时间复杂度(1)

📅  最后修改于: 2023-12-03 15:39:29.090000             🧑  作者: Mango

建立堆的时间复杂度介绍

在计算机科学中,堆(heap)是一种数据结构。堆通常是一个可以被看做一棵树的数组对象。

堆的数据结构可以被分为两类:最大堆和最小堆。最大堆:父节点的键值总是大于或等于任何一个子节点的键值;最小堆:父节点的键值总是小于或等于任何一个子节点的键值。

建立堆的时间复杂度是非常重要的,下面将对常见的建堆算法进行介绍。

堆排序

堆排序算法包括两个主要操作:将无序序列建成堆和将堆顶元素与末尾元素交换后调整成新的堆。可以通过把待排序数列构建成一个大顶堆,从而使得待排序数列中最大值为顶元素,然后把该元素与数列末尾元素交换,再把剩余的元素重新构造成一个大顶堆,然后再次交换堆顶元素与末尾元素,反复执行交换与重构建堆的操作,直到整个序列有序。

建立堆的时间复杂度:O(n),将堆顶元素与末尾元素交换后调整成新的堆的时间复杂度:O(log n)。因此,堆排序的总时间复杂度为:O(n log n)。

def heap_sort(array):
    length = len(array)
    build_heap(array, length)
    for i in range(length - 1, 0, -1):
        array[0], array[i] = array[i], array[0]
        heapify(array, i, 0)
    return array

def build_heap(array, length):
    for i in range(length // 2 - 1, -1, -1):
        heapify(array, length, i)

def heapify(array, length, i):
    largest = i
    left, right = 2 * i + 1, 2 * i + 2
    if left < length and array[left] > array[largest]:
        largest = left
    if right < length and array[right] > array[largest]:
        largest = right
    if largest != i:
        array[i], array[largest] = array[largest], array[i]
        heapify(array, length, largest)
堆的插入与删除

堆的插入操作是向堆中插入一个新元素,然后进行重构建堆;堆的删除操作是删除堆顶元素,然后进行重构建堆。

插入操作的时间复杂度为:O(log n);删除操作的时间复杂度为:O(log n)。

class MinHeap:
    def __init__(self):
        self.heap = []

    def parent(self, i):
        return (i-1)//2

    def insert_key(self, key):
        self.heap.append(key)
        i = len(self.heap)-1
        while i != 0 and self.heap[self.parent(i)] > self.heap[i]:
            self.heap[i], self.heap[self.parent(i)] = self.heap[self.parent(i)], self.heap[i]
            i = self.parent(i)

    def decrease_key(self, i, new_val):
        self.heap[i] = new_val
        while i != 0 and self.heap[self.parent(i)] > self.heap[i]:
            self.heap[i], self.heap[self.parent(i)] = self.heap[self.parent(i)], self.heap[i]
            i = self.parent(i)

    def extract_min(self):
        if len(self.heap) == 0:
            return float('inf')
        if len(self.heap) == 1:
            return self.heap.pop()
        root = self.heap[0]
        self.heap[0] = self.heap.pop()
        self.min_heapify(0)
        return root

    def delete_key(self, i):
        self.decrease_key(i, float('-inf'))
        self.extract_min()

    def min_heapify(self, i):
        l = 2*i+1
        r = 2*i+2
        smallest = i
        if l < len(self.heap) and self.heap[l] < self.heap[smallest]:
            smallest = l
        if r < len(self.heap) and self.heap[r] < self.heap[smallest]:
            smallest = r
        if smallest != i:
            self.heap[i], self.heap[smallest] = self.heap[smallest], self.heap[i]
            self.min_heapify(smallest)
延伸阅读

以上介绍的建立堆的时间复杂度都是在最坏情况下的时间复杂度。在实际应用中,平均时间复杂度也是一个重要的指标,有兴趣的读者可以了解更多。

结论

堆排序算法的时间复杂度为:O(n log n),堆的插入和删除操作的时间复杂度为:O(log n)。有了对建立堆的时间复杂度的深入了解,我们可以更好地应用堆这种数据结构。