📅  最后修改于: 2023-12-03 14:55:21.839000             🧑  作者: Mango
堆是一种树形数据结构,其中父节点的键值总是小于或等于其任何一个子节点的键值。这种堆叫做小根堆或最小堆。类似地,父节点的键值总是大于或等于其任何一个子节点的键值。这种堆叫做大根堆或最大堆。
最小堆和最大堆的主要区别在于它们对于树中节点的大小排序方式不同。在最小堆中,父节点的键值总是小于或等于其任何一个子节点的键值。这种顺序意味着堆的根节点是树中最小的节点。
在最大堆中,父节点的键值总是大于或等于其任何一个子节点的键值。这种顺序意味着堆的根节点是树中最大的节点。
堆经常用于实现各种高效的算法和数据结构,尤其是在排序算法和图算法中。堆可以用来实现优先队列、排序算法等。
实现最小堆和最大堆的具体方式也不同。最小堆通常使用模拟“下沉”操作,以确保每个父节点都小于或等于其子节点。而最大堆使用模拟“上升”操作,以确保每个父节点都大于或等于其子节点。
下面是一个使用 Python 实现最小堆的例子:
class MinHeap:
def __init__(self):
self.heap = []
def __parent(self, i):
return (i - 1) // 2
def __left(self, i):
return 2 * i + 1
def __right(self, i):
return 2 * i + 2
def __swap(self, i, j):
self.heap[i], self.heap[j] = self.heap[j], self.heap[i]
def insert(self, x):
self.heap.append(x)
i = len(self.heap) - 1
while i > 0 and self.heap[i] < self.heap[self.__parent(i)]:
self.__swap(i, self.__parent(i))
i = self.__parent(i)
def extract_min(self):
if len(self.heap) == 0:
return None
if len(self.heap) == 1:
return self.heap.pop()
root = self.heap[0]
self.heap[0] = self.heap.pop()
i = 0
while self.__left(i) < len(self.heap):
left = self.__left(i)
right = self.__right(i)
min_child = left
if right < len(self.heap) and self.heap[right] < self.heap[left]:
min_child = right
if self.heap[i] > self.heap[min_child]:
self.__swap(i, min_child)
i = min_child
else:
break
return root
这里是一个使用 Python 实现最大堆的例子:
class MaxHeap:
def __init__(self):
self.heap = []
def __parent(self, i):
return (i - 1) // 2
def __left(self, i):
return 2 * i + 1
def __right(self, i):
return 2 * i + 2
def __swap(self, i, j):
self.heap[i], self.heap[j] = self.heap[j], self.heap[i]
def insert(self, x):
self.heap.append(x)
i = len(self.heap) - 1
while i > 0 and self.heap[i] > self.heap[self.__parent(i)]:
self.__swap(i, self.__parent(i))
i = self.__parent(i)
def extract_max(self):
if len(self.heap) == 0:
return None
if len(self.heap) == 1:
return self.heap.pop()
root = self.heap[0]
self.heap[0] = self.heap.pop()
i = 0
while self.__left(i) < len(self.heap):
left = self.__left(i)
right = self.__right(i)
max_child = left
if right < len(self.heap) and self.heap[right] > self.heap[left]:
max_child = right
if self.heap[i] < self.heap[max_child]:
self.__swap(i, max_child)
i = max_child
else:
break
return root
最小堆和最大堆在堆排序和优先队列等算法中都有广泛的应用。它们的主要区别在于它们按键值大小排序的方式不同。最小堆通过模拟下沉操作,而最大堆通过模拟上升操作实现。