本文共 2391 字,大约阅读时间需要 7 分钟。
我们要明确以下几点:
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 -= 1maxPQ = 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]转载地址:http://xypbz.baihongyu.com/