📅  最后修改于: 2023-12-03 15:23:41.270000             🧑  作者: Mango
堆是一种完全二叉树,其中每个结点都具有比其子结点更高或更低的优先级。
堆广泛用于优先队列、排序算法(如堆排序)和图形算法(如最短路径和最小生成树)。
堆的基本操作有:
堆的插入和删除操作的时间复杂度均为O(log n)。堆的构建和堆化操作的时间复杂度均为O(n)。
堆可以使用数组或链表实现。在数组中,每个元素的位置称为索引,可以通过索引计算出元素在堆中的相对位置。在链表中,每个元素都包含指向其父结点、左子结点和右子结点的指针。
堆根据其优先级顺序分为最大堆和最小堆。在最大堆中,根结点的值最大,而在最小堆中,根结点的值最小。
堆还可以通过其形状分为二项堆、斐波那契堆和左倾堆等。
堆排序是一种利用堆的性质实现排序的算法。它的时间复杂度为O(n log n)。
def heap_sort(array):
n = len(array)
# 构建大根堆
for i in range(n // 2 - 1, -1, -1):
heapify(array, n, i)
# 依次取出堆顶元素,并重新构建大根堆
for i in range(n - 1, 0, -1):
array[0], array[i] = array[i], array[0]
heapify(array, i, 0)
def heapify(array, n, i):
largest = i # 初始化最大值的索引为i
left = 2 * i + 1 # 左子节点索引
right = 2 * i + 2 # 右子节点索引
# 如果左子节点比最大值大,则更新最大值的索引
if left < n and array[left] > array[largest]:
largest = left
# 如果右子节点比最大值大,则更新最大值的索引
if right < n and array[right] > array[largest]:
largest = right
# 如果最大值不是i,则交换i和最大值的位置,并递归地对交换后的子树进行堆化
if largest != i:
array[i], array[largest] = array[largest], array[i]
heapify(array, n, largest)
Dijkstra最短路径算法是一种用于在带权图中查找最短路径的算法。它使用堆来实现优先队列以提高算法效率。
import heapq
def dijkstra(graph, start):
heap = [] # 使用堆来存储待处理的元素
visited = set() # 记录已访问的节点
distances = {node: float('inf') for node in graph} # 记录节点到起点的最短距离
distances[start] = 0
heapq.heappush(heap, (0, start))
while heap:
(distance, current) = heapq.heappop(heap) # 取出堆顶元素
if current in visited:
continue
visited.add(current)
for neighbor, weight in graph[current].items():
path = distances[current] + weight
if path < distances[neighbor]:
distances[neighbor] = path
heapq.heappush(heap, (path, neighbor)) # 将相邻节点加入堆中
return distances
最小生成树算法是一种在带权图中找到最小生成树的算法。它使用堆来实现优先队列以提高算法效率。
import heapq
def prim(graph, start):
heap = [] # 使用堆来存储待处理的元素
visited = set() # 记录已访问的节点
minimum_spanning_tree = set() # 存储最小生成树
visited.add(start)
for neighbor, weight in graph[start].items():
heapq.heappush(heap, (weight, (start, neighbor)))
while heap:
(weight, (current, next_node)) = heapq.heappop(heap) # 取出堆顶元素
if next_node not in visited:
visited.add(next_node)
minimum_spanning_tree.add((current, next_node, weight))
for neighbor, weight in graph[next_node].items():
if neighbor not in visited:
heapq.heappush(heap, (weight, (next_node, neighbor)))
return minimum_spanning_tree
堆是一种重要的数据结构,它具有广泛的应用,包括优先队列、排序算法和图形算法。在实现堆时,需要考虑其基本操作、种类和实现方式。堆排序、Dijkstra最短路径算法和最小生成树算法是堆的应用案例。