原理
总是在算法题中用到堆,但是一直都是使用python自带的小根堆,对于堆的原理也不是很了解,所以抽时好好打一下基础,自己动手写代码,能有更深的了解
原理方面主要参考了以下博客:
数据结构-堆(heap)与堆的Python实现
python实现堆插入、删除、创建
另外说一句,技术这种东西,别人开源的思路,你既然参考了,就一定要尊重原创,每个人都是从菜鸟一步步学习起来的,参考前人的内容也不是什么丢人的事情,比如,力扣就发生了这样的事情,我支持评论区大佬们的观点:
链接
还有,我就不理解为什么非要有人把自己的博客设置成为仅粉丝可见,多那几个粉丝就那么重要嘛?文章写得好,自然会有人愿意关注你;整体水平就那样,即使因为某篇博客不得不关注,之后也是会取消的,建议别搞这些无聊的东西
代码
代码还有很多功能没添加,并且有些逻辑也显得不够优雅,是一个最基础的版本,正因为功能少,所以也有助于了解堆的原理
class minheap:
def __init__(self):
self.q = []
def heapinsert(self, val):
self.q.append(val)
self.totop()
def totop(self):
i = len(self.q)-1
while i > 0:
father = (i-1) // 2
if self.q[i] < self.q[father]:
self.q[i], self.q[father] = self.q[father], self.q[i]
i = father
else:
break
def heappop(self):
if not self.q:
raise Exception('The heap is empty!')
last = len(self.q)-1
self.q[0], self.q[last] = self.q[last], self.q[0]
res = self.q.pop()
self.todown()
return res
def todown(self):
i = 0
while 2*i+2 < len(self.q):
left = 2*i+1
right = 2*i+2
# 分情况讨论,判断i去往左孩子还是右孩子
if self.q[left] < self.q[i] and self.q[left] <= self.q[right]:
self.q[i], self.q[left] = self.q[left], self.q[i]
i = left
elif self.q[right] < self.q[i] and self.q[right] <= self.q[left]:
self.q[i], self.q[right] = self.q[right], self.q[i]
i = right
else:
break
# 如果还有左孩子
left = 2*i+1
if left < len(self.q) and self.q[left] < self.q[i]:
self.q[i], self.q[left] = self.q[left], self.q[i]
if __name__ == '__main__':
import random
# 测试10000次
for _ in range(10000):
# 生成随机长度随机数组
arr = []
for _ in range(random.randint(1,100)):
arr.append(random.randint(1,100))
# print(arr)
n = len(arr)
q = minheap()
for i in arr:
q.heapinsert(i)
# print(q.q)
res = []
for _ in range(n):
res.append(q.heappop())
# print(res)
if sorted(arr) != res:
print('something wrong!')
print('success!')