优先级队列

"""
first in first out
高优先级的先出,
"""


class Array(object):
    def __init__(self, size=32):
        self.size = size
        self.items = [None]*self.size
        
    def __getitem__(self, item):
        if item >= self.size and item < 1:
            raise Exception('越界')
            
        return self.items[item]
        
    def __setitem__(self, item, value):
        if item >= self.size and item < 1:
            raise Exception('越界')
            
        self.items[item] = value
        
    def __len__(self):
        return self.size
        
    def clear(self, value=None):
        for i in range(self.size):
            self.items[i] = value
            
    def __iter__(self):
        for item in self.items:
            yield item


class MaxHeap(object):
    def __init__(self, maxsize=32):
        self._maxsize = maxsize
        self._elements = Array(self._maxsize)
        self.count = 0
        
    def __len__(self):
        return self.count
        
    def add(self, value):
        if self.count >= self._maxsize:
            raise Exception('full error')
        self._elements[self.count] = value
        self.count +=1
        self._siftup(self.count-1)
        
    def _siftup(self, index):
        """
        递归交换
        维持最大堆的特性
        """
        if index > 0:
            parent = int((index-1)/2)
            if self._elements[index] > self._elements[parent]:
                self._elements[index], self._elements[parent] = self._elements[parent], self._elements[index]
                self._siftup(parent)
                
    def extrack(self):
        if self.count <= 0:
            raise Exception('expty')
        value = self._elements[0]
        self.count -= 1
        self._elements[0] = self._elements[self.count]
        self._siftdown(0)
        return value
        
    def _siftdown(self, index):
        left = 2*index+1
        rigth = 2*index+2
        largest = index
        
        if (left < self.count and  # 判断是否有左孩子
                self._elements[left] >= self._elements[largest] and
                self._elements[left] >= self._elements[rigth]):  # 左孩子>右孩子
            largest = left
        if (rigth < self.count and self._elements[rigth] >= self._elements[largest]):
            largest = rigth
            
        if largest != index:
            self._elements[index], self._elements[largest] = self._elements[largest], self._elements[index]
            self._siftdown(largest)
            
    def hahah(self):
        for i in self._elements:
            print(i)
    
    
class Priority(object):
    def __init__(self, max_size=32):
        self._max_size = max_size
        self._maxheap = MaxHeap(self._max_size)
        
    def push(self, priority, value):
        entry = (priority, value)
        self._maxheap.add(entry)
        
    def pop(self, with_priority=False):
        entry = self._maxheap.extrack()
        if with_priority:
            return entry
        else:
            return entry[1]
        
    def is_empty(self):
        return len(self._maxheap) == 0
        pass


def test_priority_queue():
    size = 10
    pq = Priority(size)
    pq.push(5, 'purple')
    pq.push(0, 'white')
    pq.push(3, 'organge')
    pq.push(1, 'black')
    
    res = []
    while not pq.is_empty():
        res.append(pq.pop())
    assert res == ['purple', 'organge', 'black', 'white']
    assert 0

 

posted @ 2020-05-05 02:50  SBJBA  阅读(81)  评论(0)    收藏  举报