Fork me on GitHub

【python刷题】二叉堆-优先级队列

我们要明确以下几点:
1、二叉堆是一棵完全二叉树;
2、可以构造大顶堆和小顶堆;
3、二叉堆构建优先级队列,以大顶堆为例,每次出队列的值都是当前队列中的最大值;

class MaxPQ:
    def __init__(self):
        self.n = 0  # 当前优先级队列中的元素,优先级队列:插入或删除元素的时候,元素会自动排序
        self.pq = [0]  # 存储数组,0索引位置不用

    def parent(self, root):
        return root // 2

    def left(self, root):
        return root * 2

    def right(self, root):
        return root * 2 + 1

    def getMax(self):
        return self.pq[1]

    def insert(self, x):
        self.n += 1
        self.pq.append(x)
        self.up(self.n)

    def delMax(self):
        m = self.pq[1]
        self.swap(1, self.n)
        self.pq.pop()
        self.n -= 1
        self.down(1)
        return m

    def maxChildInd(self, x):
        # 如果右孩子为空,返回左孩子的索引
        if self.right(x) > self.n:
            return self.left(x)
        else:
            if self.less(self.left(x), self.right(x)):
                return self.right(x)
            else:
                return self.left(x)

    # 上浮第x个元素
    def up(self, x):
        while self.parent(x) > 0:
            # 如果新节点小于父节点
            if self.pq[x] > self.pq[self.parent(x)]:
                self.swap(self.parent(x), x)
            x = self.parent(x)


    # 下浮第x个元素
    def down(self, x):
        while self.left(x) <= self.n:
            # 返回值较大的那个的索引
            tmp = self.maxChildInd(x)
            if self.pq[tmp] > self.pq[x]:
                self.swap(tmp, x)
            x = tmp

    # 交换两个元素
    def swap(self, i, j):
        self.pq[i],self.pq[j] = self.pq[j],self.pq[i]

    # pq[i]是否比pq[j]小
    def less(self, i, j):
        return self.pq[i] < self.pq[j]

    def buildHeap(self, alist):
        self.pq = self.pq + alist
        self.n = len(alist)
        ind = self.n // 2
        while ind > 0:
            self.down(ind)
            ind -= 1

maxPQ = MaxPQ()
maxPQ.buildHeap([78, 83, 82, 80, 79, 65, 84])
print("初始的pq:", maxPQ.pq)
print(maxPQ.delMax())
print(maxPQ.pq)
print(maxPQ.delMax())
print(maxPQ.pq)
print(maxPQ.delMax())
print(maxPQ.pq)
print(maxPQ.delMax())
print(maxPQ.pq)
print(maxPQ.delMax())
print(maxPQ.pq)
maxPQ.insert(67)
print("插入67之后的pq:", maxPQ.pq)
print(maxPQ.delMax())
print(maxPQ.pq)
maxPQ.insert(66)
print("插入66之后的pq:", maxPQ.pq)
print(maxPQ.delMax())
print(maxPQ.pq)

结果:
初始的pq: [0, 84, 83, 82, 80, 79, 65, 78]
84
[0, 83, 80, 82, 78, 79, 65]
83
[0, 82, 80, 65, 78, 79]
82
[0, 80, 79, 65, 78]
80
[0, 79, 78, 65]
79
[0, 78, 65]
插入67之后的pq: [0, 78, 65, 67]
78
[0, 67, 65]
插入66之后的pq: [0, 67, 65, 66]
67
[0, 66, 65]

posted @ 2021-02-01 19:20  西西嘛呦  阅读(100)  评论(0编辑  收藏  举报