1、堆的代码实现
class Heap:
"""
既可以通过单个元素插入的方式建堆
也可以通过build_heap()传入现有列表的方式建堆(建堆时容量要匹配)
"""
def __init__(self,capacity):
"""
:param capacity: 堆的容量,可通过现有列表的len传入
"""
self._array = [None]*capacity
self._count = 0
self.capacity = capacity
def insert(self,value):
"""
向堆内插入元素
:param value:
:return:
"""
if self._count == self.capacity:
print('heap is full')
return
self._array[self._count] = value
curr_indx = self._count
while (curr_indx-1)//2>=0 and self._array[curr_indx] > self._array[(curr_indx-1)//2]:
self._array[curr_indx],self._array[(curr_indx-1)//2]=self._array[(curr_indx-1)//2],self._array[curr_indx]
curr_indx = (curr_indx-1)//2
self._count += 1
def pop_top(self):
"""
弹出堆顶元素
并更新堆
:return:
"""
top_value = self._array[0]
self._array[0],self._array[self._count-1] = self._array[self._count-1],None
self._count-=1
curr_indx = 0
while True:
left_value = self._array[curr_indx*2+1] if curr_indx*2+1 < self._count else 0
right_value = self._array[curr_indx * 2+2] if curr_indx * 2+2 < self._count else 0
if left_value>right_value and self._array[curr_indx] <left_value:
self._array[curr_indx], self._array[curr_indx*2+1] = self._array[curr_indx*2+1], self._array[curr_indx]
curr_indx = curr_indx*2+1
elif left_value<right_value and self._array[curr_indx] <right_value:
self._array[curr_indx], self._array[curr_indx*2+2] = self._array[curr_indx*2+2], self._array[curr_indx]
curr_indx = curr_indx*2+2
else:
break
return top_value
def print_heap(self):
"""
按列表顺序打印堆内元素
:return:
"""
print(self._array)
def build_heap(self,array_list):
"""
把现有列表变成堆结构
:param array_list:
:return:
"""
self._array = array_list
for v in self._array:
self.insert(v)
def sort_heap(self):
"""
将堆改变为升序排列
:return:
"""
curr_indx = self._count-1
for v in self._array:
self._array[curr_indx] = self.pop_top()
curr_indx-=1
if __name__ == '__main__':
arr = [5,1,3,4,2,6,7,9,10,15]
hp = Heap(len(arr))
hp.build_heap(arr)
print(arr)
hp.sort_heap()
print(arr)
2、堆的应用
1.优先级队列
- 合并小文件
- 高效定时器
2.求TopK
3.求中位数