堆(heap),又被为优先队列(priority queue), 是一种经过排序的完全二叉树,其任一非叶子节点的值均不大于(或不小于)其左孩子和右孩子节点的值。
将 \(O(n)\) 个元素逐一插入到一个空堆中,时间复杂度是 \(O(n\log n)\);
heapify()
的过程,时间复杂度是 \(O(n)\),[参考];
class Heap(object):
def __init__(self) -> None:
self.data_list = []
def get_parent_index(self, index):
if index == 0 or index > len(self.data_list) - 1:
return None
else:
return (index - 1) >> 1
def swap(self, index_0, index_1):
self.data_list[index_0], self.data_list[index_1] = self.data_list[index_1], self.data_list[index_0]
def insert(self, data):
self.data_list.append(data)
index = len(self.data_list) - 1
parent = self.get_parent_index(index)
while parent is not None and self.data_list[parent] < self.data_list[index]:
self.swap(parent, index)
index = parent
parent = self.get_parent_index(index)
def remove_max(self):
remove_data = self.data_list[0]
self.data_list[0] = self.data_list[-1]
del self.data_list[-1]
self.heapify(0, len(self.data_list) - 1)
return remove_data
def heapify(self, index, total_index):
while True:
maxvalue_index = index
if 2 * index + 1 <= total_index and self.data_list[2 * index + 1] > self.data_list[maxvalue_index]:
maxvalue_index = 2 * index + 1
if 2 * index + 2 <= total_index and self.data_list[2 * index + 2] > self.data_list[maxvalue_index]:
maxvalue_index = 2 * index + 2
if maxvalue_index == index:
break
self.swap(index, maxvalue_index)
index = maxvalue_index
def heap_init(self):
len_heap = len(self.data_list)
# Build a maxheap.
for i in range(len_heap - 1, -1, -1):
self.heapify(i, len_heap - 1)
def heap_sort(self):
self.heap_init()
len_heap = len(self.data_list)
# Sort
for i in range(len_heap - 1, 0, -1):
self.data_list[0], self.data_list[i] = self.data_list[i], self.data_list[0]
self.heapify(0, i - 1)
arr = [ 12, 11, 13, 5, 6, 7, -1]
heap = Heap()
heap.data_list = arr[:]
heap.heap_init()
# heap.heap_sort()
print(arr)
while len(heap.data_list) > 0:
max_data = heap.remove_max()
print(max_data)