📅  最后修改于: 2023-12-03 15:40:01.167000             🧑  作者: Mango
在计算机科学中,堆(heap)是一种抽象数据类型,它是一种特殊的树形数据结构。它常常被应用在算法中,例如堆排序以及图形中的最小生成树算法。
堆的特征是根节点的键值最大或最小,在堆中根节点总是最值。堆可以分为最大堆和最小堆。最大堆的根节点是最大值,最小堆的根节点是最小值。
堆通常是由数组实现的。在数组表示的堆中,如果一个结点的下标为i,则它的父节点、左子节点和右子节点的下标分别为(i - 1)/ 2、2 * i + 1 和 2 * i + 2。
下面给出一个Python实现的最大堆,其中包括堆的初始化、插入、删除以及堆排序等操作:
class Heap:
def __init__(self, items=[]):
super().__init__()
self.heap = [0]
for item in items:
self.heap.append(item)
self.__float_up(len(self.heap) - 1)
def push(self, item):
self.heap.append(item)
self.__float_up(len(self.heap) - 1)
def pop(self):
if len(self.heap) > 2:
self.__swap(1, len(self.heap) - 1)
max_item = self.heap.pop()
self.__bubble_down(1)
elif len(self.heap) == 2:
max_item = self.heap.pop()
else:
max_item = False
return max_item
def sort(self):
result = []
while True:
item = self.pop()
if item:
result.append(item)
else:
break
return result
def __swap(self, i, j):
self.heap[i], self.heap[j] = self.heap[j], self.heap[i]
def __float_up(self, index):
parent_index = index // 2
if parent_index <= 0:
return
elif self.heap[parent_index] < self.heap[index]:
self.__swap(parent_index, index)
self.__float_up(parent_index)
def __bubble_down(self, index):
child_index = self.__get_bigger_child_index(index)
if child_index == -1:
return
elif self.heap[child_index] > self.heap[index]:
self.__swap(child_index, index)
self.__bubble_down(child_index)
def __get_bigger_child_index(self, index):
left_child_index = index * 2
right_child_index = index * 2 + 1
if left_child_index >= len(self.heap):
return -1
elif right_child_index >= len(self.heap):
return left_child_index
elif self.heap[left_child_index] > self.heap[right_child_index]:
return left_child_index
else:
return right_child_index
可以看到,这个最大堆的实现方法很简单。堆的插入操作可以通过将元素插入到最后再执行__float_up操作完成。而堆排序操作又可以通过pop操作,每次弹出(删除)堆中的最大元素并将其添加到结果列表中。
同时,堆也可以应用于解决一些具体的问题,例如堆叠问题。堆叠问题是指对一堆数据进行堆化操作,使其满足一些特定的要求,常常应用于优先队列等场景中。下面是一个应用堆的例子:
假设有一个长度为n的数组arr,现在要用前m小的数来凑成一个数s,那么可以利用堆求出前m小的数。同时,也可以通过重新排序完成前m小的数。
def find_min_m_sum(arr, m, s):
heap = Heap()
for item in arr:
heap.push(-item)
if len(heap.heap) > m + 1:
heap.pop()
if len(heap.heap) <= 1:
return []
min_items = [-i for i in heap.sort()[1:]]
if sum(min_items) < s:
return []
result = []
for item in min_items:
if sum(result) + item <= s:
result.append(item)
else:
break
return result
上述代码中,find_min_m_sum函数通过弹出前m小的数来筛选出最小的m个数。最后,将前m小的数累加起来,然后与给定的s进行比较,返回满足要求的子序列。
堆是一种非常重要的数据结构,在日常的开发过程中经常会被用到。学习和掌握堆的相关知识和应用,将会为你的开发工作带来很大的帮助。