优先队列的堆实现(python语言)

# -*- coding: UTF-8 -*-


class PrioQueue:  # 优先队列类
    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)  # 添加一个元素
        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 dequue(self):  # 出队
        if self.is_empty():
            raise PrioQueueError('in peek')  # 为空时返回错误
        elems = self._elems
        e0 = elems[0]
        e = elems.pop()
        if len(elems):  # 审查
            self.siftdown(e, 0, len(elems))
        return e0

    def siftdown(self, e, begin, end):  # 筛分
        elems, i, j = self._elems, begin, begin * 2 + 1
        while j < end:
            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.siftdown(self._elems[i], i, end)

堆排序

# -*- coding: UTF-8 -*-


class PrioQueue:  # 优先队列类
    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)  # 添加一个元素
        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 dequue(self):  # 出队
        if self.is_empty():
            raise PrioQueueError('in peek')  # 为空时返回错误
        elems = self._elems
        e0 = elems[0]
        e = elems.pop()
        if len(elems):  # 审查
            self.siftdown(e, 0, len(elems))
        return e0

    def siftdown(self, e, begin, end):  # 筛分
        elems, i, j = self._elems, begin, begin * 2 + 1
        while j < end:
            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.siftdown(self._elems[i], i, end)

    def heap_sort(elems):  # 堆排序
        def siftdown(elem, e, begin, end):  # 审查
            i, j = begin, begin * 2 + 1
            while j < end:
                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):  # 建堆,从i开始以end为建堆范围的边界
            siftdown(elems, elems[i], i, end)
        for i in range((end - 1), 0, -1):  # 逐个取出最小元素,将其积累到标的最后,放一个退一步
            e = elems[i]
            elems[i] = elems[0]
            siftdown(elems, e, 0, i)

猜你喜欢

转载自blog.csdn.net/zhangyu4863/article/details/80600050