# -*- coding:utf-8 -*-
class Array(object):
def __init__(self,size=32):
self._size = size
self._items = [None] * size
def __getitem__(self,index):
return self._items[index]
def __setitem__(self,index,value):
self._items[index] = value
def __len__(self):
return self._size
def clear(self,value=None):
for i in range(self._items):
self._items[i] = value
def __iter__(self):
for item in self._items:
yield item
'''
初始化堆结构
'''
class MaxHeap(object):
def __init__(self,maxsize=None):
self.maxsize = maxsize
self._elements = Array(maxsize)
self._count = 0
def __len__(self):
return self._count
def add(self,value):
if self._count >= self.maxsize:
raise Exception('full')
#将插入的值value给数组最后一值
self._elements[self._count] = value
#堆的容量加一
self._count += 1
self._siftup(self._count-1)
def _siftup(self,ndx): #递归交换直到满足最大堆特性
if ndx > 0:
#获取添加节点的父节点的下标值
parent = int((ndx-1)/2)
#如果添加节点的值大于父节点的值
if self._elements[ndx] > self._elements[parent]:
self._elements[ndx],self._elements[parent] = self._elements[parent],self._elements[ndx]
self._siftup(parent)
def extract(self):
if self._count <= 0:
raise Exception('empty')
#获取根节点的值
value = self._elements[0]
#将堆最后一个叶子节点作为root节点
self._elements[0] = self._elements[self._count]
self._siftdown(0)
return value
def _siftdown(self,ndx):
#获取左右孩子节点的下标
left = 2 * ndx + 1
right = 2 * ndx + 2
#默认ndx为最大
largest = ndx
if(left < self._count and #有左孩子
self._elements[left] >= self._elements[largest] and
self._elements[left] >= self._elements[right]): #左孩子 > 右孩子
largest = left
elif right < self._count and self._elements[right] >= self._elements[largest]:
largest = right
if largest != ndx:
self._elements[ndx],self._elements[largest] = self._elements[largest],self._elements[ndx]
self._siftdown(largest)
def test_priority_queue():
size = 5
pq = PriorityQueue(size)
pq.push(5,'purple')
pq.push(0,'white')
pq.push(3,'orange')
pq.push(1,'black')
res = []
while not pq.is_empty():
res.append(pq.pop())
assert res == ['purple','orange','black','white']
class PriorityQueue(object):
def __init__(self,maxsize=None):
self.maxsize = maxsize
self._maxheap = MaxHeap(maxsize)
def push(self,priority,value):
entry = (priority,value) #push a tuple
self._maxheap.add(entry)
def pop(self,with_priority=False):
entry = self._maxheap.extract()
if with_priority:
return entry #return a tuple
else:
return entry[1]
def is_empty(self):
return len(self._maxheap) == 0
python-优先级队列
最新推荐文章于 2024-04-12 20:43:32 发布