Python 数据结构 优先队列

基于list实现的优先队列

class PrioQueueError(ValueError):
    pass
class PrioQue:
    def __init__(self, elist=[]):
        self._elems = list(elist)           # 1.对实参表做拷贝,避免共享。2.使构造函数的实参可以使任何可迭代对象。
        self._elems.sort(reverse=True)      # 较小作为优先级
    
    def enqueue(self, e):
    '''
    while的条件循环保证优先度相同元素的正确排序顺序,
    使同优先级的元素能先进先出
    '''
        i = len(self._elems) - 1
        while i >= 0:
            if self._elems[i] <= e:
                i -= e
            else:
                break
        self._elems.insert(i+1, e)
    
    def is_empty(self):
        return not self._elems
    
    def peek(self):
        if self.is_empty():
            raise PrioQueueError("in top")
        return self._elems[-1]
    
    def dequeue(self):
        if self.is_empty():
            raise PrioQueueError("in top")
        return self._elems.pop()

 

优先队列的堆实现

'''
插入元素:O(logn)
    把新加入元素放在已有元素之后,执行一次向上筛选操作
    向上筛选操作中比较和交换次数不会超过二叉树中最长路径, 
弹出元素:O(logn)
    弹出当时的堆顶
    从堆最后去一个元素作为完全二叉树
    执行一次向下筛选
'''
class PrioQueue:
    """ Implementing priority queues using heaps
    """
    def __init__(self, elist=[]):
        self._elems = list(elist)
        if elist:
            self.buildheap()

    def is_empty(self):
        return not self._elems

    def peek(self):
        if self.is_empty():
            raise PrioQueueError("in peek")
        return self._elems[0]

    def enqueue(self, e):
        self._elems.append(None)    # add a dummy element
        self.siftup(e, len(self._elems)-1)

    def siftup(self, e, last):
        elems, i, j = self._elems, last, (last-1)//2
        while i > 0 and e < elems[j]:
            elems[i] = elems[j]
            i, j = j, (j-1)//2
        elems[i] = e

    def dequeue(self):
        if self.is_empty():
            raise PrioQueueError("in dequeue")
        elems = self._elems
        e0 = elems[0]
        e = elems.pop()
        if len(eles) > 0:
            self.siftdowm(e, 0, len(elems))
        return e0

    def siftdowm(self, e, beign, end):
        elems, i, j = self._elems, begin, begin*2 + 1
        while j < end:              # invariant: j == 2*i+1
            if j+1 < end and elems[j+1] < elems[j]:
                j += 1              # elems[j]不大于其兄弟节点的数据
            if e < elems[j]:        # e在三者中最小,已找到了位置
                break
            elems[i] = elems[j]     # elems{j}在三者中最小,上移
            i, j = j, 2*j+1
        elems[i] = e

    def buildheap(self):
        end = len(self._elems)
        for i in range(end//2, -1, -1):
            self.siftdowm(self._elems[i], i, end)

 

堆的应用:堆排序

def head_sort(elems):
    def siftdowm(elems, e, begin, end):
        i, j = beign, begin*2+1
        while j < end:              # invariant: j == 2*i+1
            if j+1 < end and elems[j+1] < elems[j]:
                j += 1              # elems[j]不大于其兄弟节点的数据
            if e < elems[j]:        # e在三者中最小,已找到了位置
                break
            elems[i] = elems[j]     # elems{j}在三者中最小,上移
            i, j = j, 2*j+1
        elems[i] = e
    
    end = len(elems)
    for i in range(end//2, -1, -1):
        siftdowm(elems, elems[i], i, end)
    for i in range((end-1), 0, -1):
        e = elems[i]
        elems[i] = elems[0]
        siftdowm(elems, e, 0, i)

 

你可能感兴趣的:(算法,python)