📅  最后修改于: 2023-12-03 15:08:08.802000             🧑  作者: Mango
堆是一种基于树的数据结构,可以用数组实现。它的一个重要应用是用来实现优先队列。 堆是一个完全二叉树,且满足堆特性:对于一颗以 i 为根的子树,要么这颗子树为空,要么满足以下条件:
堆有两种类型:最大堆和最小堆。
在最大堆中,根节点的值最大,每个子节点的值都小于等于它的父节点的值。
在最小堆中,根节点的值最小,每个子节点的值都大于等于它的父节点的值。
堆可以使用数组来实现,因为堆的结构可以看作树形结构的一个数组,每个节点在数组中的下标满足以下规则:
可以通过数组实现堆的插入和删除操作。
插入操作通常是将新元素添加到堆的底部,然后一直交换它与它的父节点,直到满足堆的特性。伪代码如下:
Insert(heap, x):
heap.add(x)
i = heap.length - 1
while i > 0 and heap[i] > heap[parent(i)]:
swap(heap[i], heap[parent(i)])
i = parent(i)
删除操作通常是将堆的根节点删除并将堆的底部元素替换为根,然后一直交换它与它的子节点,直到满足堆的特性。伪代码如下:
Delete(heap):
if heap.length == 0:
throw error "Heap is empty"
max = heap[0]
last = heap[-1]
heap.pop()
if heap.length > 0:
heap[0] = last
heapify(heap, 0)
return max
heapify(heap, i):
left = 2*i + 1
right = 2*i + 2
largest = i
if left < heap.length and heap[left] > heap[largest]:
largest = left
if right < heap.length and heap[right] > heap[largest]:
largest = right
if largest != i:
swap(heap[i], heap[largest])
heapify(heap, largest)
堆最常见的应用是实现优先队列。使用堆作为优先队列的底层数据结构可以实现 O(log n) 的插入和删除操作,因此在需要频繁插入和删除元素的场合非常有效。
除了优先队列,堆还有其他一些应用,如求 Top k 问题、排序等。
堆是一种非常重要的基础数据结构,可以用来实现优先队列等许多应用。它的操作并不复杂,但需要对其特性和实现方法有清晰的认识。