最小堆和最大堆采用完全二叉树的形式来存储不同数字的序列,在topK问题中有广泛应用。其满足中间节点大于左子树和右子树上所有节点值的特点,为保证其存储、查找和删除的遍历,通常采用数组的形式进行构建。
本文实现了最小堆和最大堆的构建、堆顶查找、堆顶删除、插入等基本功能。
- 最小堆
class minBinaryHeap(object):
def __init__(self):
self.heap = [0]
self.length = 0
def isEmpty(self):
return self.length == 0
def insert(self, k):
self.heap.append(k)
self.length += 1
i = self.length
while i // 2 > 0:
if self.heap[i // 2] > self.heap[i]:
self.heap[i // 2], self.heap[i] = self.heap[i], self.heap[i // 2]
i //= 2
else:
break
def finMin(self):
return self.heap[1]
def delMin(self):
# 删除最小堆对顶
if self.isEmpty():
raise ValueError("It is empty binary heap!")
# 1. 将完全二叉树的最后一个元素挪至堆顶
self.heap[1] = self.heap.pop()
self.length -= 1
# 2. 将堆顶进行下沉
i = 1
while i * 2 <= self.length:
minIndex = i * 2
if i * 2 + 1 <= self.length and self.heap[i * 2] > self.heap[i * 2 + 1]:
minIndex = i * 2 + 1
if self.heap[minIndex] < self.heap[i]:
self.heap[i], self.heap[minIndex] = self.heap[minIndex], self.heap[i]
else:
break
i += 1
def bulidHeap(self, nums: list):
# 从中间节点开始,对每个元素采用下沉法找到位置
assert self.length == 0
self.heap = [0] + nums
self.length = len(nums)
i = self.length // 2
while i > 0:
j = i
while j * 2 <= self.length:
minIndex = j * 2
if j * 2 + 1 <= self.length and self.heap[j * 2] > self.heap[j * 2 + 1]:
minIndex = j * 2 + 1
if self.heap[minIndex] < self.heap[j]:
self.heap[j], self.heap[minIndex] = self.heap[minIndex], self.heap[j]
else:
break
j += 1
i -= 1
def size(self):
return self.length
def __repr__(self):
return str(self.heap[1:])
- 最大堆
class maxBinaryHeap(object):
def __init__(self):
self.heap = [0]
self.length = 0
def isEmpty(self):
return self.length == 0
def insert(self, k):
self.heap.append(k)
self.length += 1
i = self.length
while i // 2 > 0:
if self.heap[i // 2] < self.heap[i]:
self.heap[i // 2], self.heap[i] = self.heap[i], self.heap[i // 2]
i //= 2
else:
break
def finMax(self):
return self.heap[1]
def delMax(self):
# 删除最小堆对顶
if self.isEmpty():
raise ValueError("It is empty binary heap!")
# 1. 将完全二叉树的最后一个元素挪至堆顶
self.heap[1] = self.heap.pop()
self.length -= 1
# 2. 将堆顶进行下沉
i = 1
while i * 2 <= self.length:
maxIndex = i * 2
if i * 2 + 1 <= self.length and self.heap[i * 2] < self.heap[i * 2 + 1]:
maxIndex = i * 2 + 1
if self.heap[maxIndex] > self.heap[i]:
self.heap[i], self.heap[maxIndex] = self.heap[maxIndex], self.heap[i]
else:
break
i += 1
def bulidHeap(self, nums: list):
# 从中间节点开始,对每个元素采用下沉法找到位置
assert self.length == 0
self.heap = [0] + nums
self.length = len(nums)
i = self.length // 2
while i > 0:
j = i
while j * 2 <= self.length:
maxIndex = j * 2
if j * 2 + 1 <= self.length and self.heap[j * 2] < self.heap[j * 2 + 1]:
maxIndex = j * 2 + 1
if self.heap[maxIndex] > self.heap[j]:
self.heap[j], self.heap[maxIndex] = self.heap[maxIndex], self.heap[j]
else:
break
j += 1
i -= 1
def size(self):
return self.length
def __repr__(self):
return str(self.heap[1:])