用二叉堆实现优先队列 Priority Queue

优先队列出队跟队列一样,从队首出队;但队内的次序由优先级决定,即优先级高的数据项可以插队,排到前面。
二叉堆能够将优先队列的入队和出队复杂度都保持在O(logn)
完全二叉树,如果用顺序表来表示的话,设根节点下标为1,若某节点下标为p,则其左子节点下标为2p,右子节点下标为2p+1,父节点下标为p//2.

最小二叉堆代码:

class BinaryHeap:
    def __init__(self):
        self.heapList=[0]   #用0占位,使得下标从1开始
        self.currentSize=0
    
    def percUp(self,i):  #上浮,跟父节点比大小
        while i//2>0:
            if self.heapList[i] < self.heapList[i//2]:
                self.heapList[i],self.heapList[i//2]=self.heapList[i//2],self.heapList[i]
            else:
                break  #如果没有父节点大,则无需继续上浮比较
            i//=2
    
    def insert(self,item):
        self.heapList.append(item)
        self.currentSize+=1
        self.percUp(self.currentSize)
        
    def percDown(self,i): #下沉,若大于子节点,则每次跟子节点中最小的进行交换
        while 2*i<=self.currentSize: #若还有子节点
            if 2*i+1<=self.currentSize: #如果右节点还存在
                minIndex=2*i if self.heapList[2*i]<self.heapList[2*i+1] else 2*i+1
            else: #右节点不存在
                minIndex=2*i
            if self.heapList[i]>self.heapList[minIndex]:
                self.heapList[i],self.heapList[minIndex]=self.heapList[minIndex],self.heapList[i]
                i=minIndex
            else:
                break
    
    def delMin(self): #移走根节点,之后为了保持完全二叉树的结构,需要把最后一个数据项补到根节点,之后再进行下沉操作
        minVal=self.heapList[1]
        self.heapList[1]=self.heapList[self.currentSize]
        self.heapList.pop()
        self.currentSize-=1
        self.percDown(1)
        return minVal
    
    def buildHeap(self,alist):
        self.heapList=[0]+alist
        self.currentSize=len(alist)
        i=self.currentSize//2  #从最后一个节点的父节点开始下沉
        while i>0:
            self.percDown(i)
            i-=1
        return self.heapList

r=BinaryHeap()
alist=[1,6,4,5,3,8,9,0]
print(r.buildHeap(alist))
r.delMin()
print(r.heapList)
r.insert(2)
print(r.heapList)

输出

[0, 0, 1, 4, 5, 3, 8, 9, 6]
[0, 1, 3, 4, 5, 6, 8, 9]
[0, 1, 2, 4, 3, 6, 8, 9, 5]

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值