📅  最后修改于: 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)。有了对建立堆的时间复杂度的深入了解,我们可以更好地应用堆这种数据结构。