python -自底而上的构建堆,基于堆的优先级队列


堆(英语:heap)是计算机科学中一类特殊的数据结构的统称。堆通常是一个可以被看做一棵树的数组对象。堆总是满足下列性质:
堆中某个节点的值总是不大于或不小于其父节点的值;
堆总是一棵完全二叉树。
将根节点最大的堆叫做最大堆或大根堆,根节点最小的堆叫做最小堆或小根堆

基于数组的完全二叉树表示
如果p是T的根节点,则f§=0
如果p是位置q的左孩子,则 f§=2f(q)+1
如果p是位置q的右孩子,则f§=2
f(q)+2
1我们用数组来表示一棵二叉树
自底向上构建堆
如初始序列为 3 4 5 7 9 1 2 10 11
完全二叉树
在这里插入图片描述在这里插入图片描述

根据这个完全二叉树构造成小根堆,就要从最后一个具有孩子节点的节点开始不断让其向下调整 ,所以应该从7开始调整,它是最后一个节点的双亲节点所以很容易定位到它 7比2小交换 然后接着调整5 5比1小交换 接着调整4 4 比2小交换 最后调整3 3比1小交换

基于堆的优先级队列实现

class Empty:
    pass
class PriorityQueueBase:
    class _Item:
        def __init__(self,k,v):
            self._key=k#键
            self._value=v#值
        def __It__(self,other):
            return self._key<other._key
    def is_empty(self):
        return len(self)==0
class HeapPriorityQueue(PriorityQueueBase):
    def __init__(self,content=()):#初始化,用列表作为存储结构
        #self._data=[]
        self._data=[self._Item(k,v) for k,v in content]
        if len(self._data)>1:
           self._heapify()
    def _heapify(self):
        start = self._parent(len(self._data) - 1)
        for i in range(start, -1, -1):
            self._downheap(i)
    def _parent(self,j):#返回下标为j的元素的父节点下标
        return (j-1)//2
    def _left(self,j):#返回下标为j的元素的左孩子下标
        return 2*j+1
    def _right(self,j):#返回下标为j的元素的右孩子下标
        return 2*j+2
    def _has_left(self,j):#判断下标为j的元素是否有左孩子
       return self._left(j)<len(self._data)
    def _has_right(self,j):#判断下标为j的元素是否有右孩子
      return self._right(j)<len(self._data)
    def _swap(self,i,j):#交换self._data数组中下标为i,j的值
        self._data[i],self._data[j]=self._data[j],self._data[i]
    def _upheap(self,j):#自下而上的调整堆
        parent=self._parent(j)
        if j>0 and self._data[j].__It__(self._data[parent]):
            self._swap(j,parent)
            self._upheap(parent)
    def _downheap(self,j):#自上而下的调整堆
        if self._has_left(j):
            left=self._left(j)
            smallchild=left
            if self._has_right(j):
                right=self._right(j)
                if self._data[right].__It__(self._data[left]):
                    smallchild=right
            if self._data[smallchild].__It__(self._data[j]):
                self._swap(j,smallchild)
                self._downheap(smallchild)
    def __len__(self):
          return len(self._data)
    def add(self,key,value):
        node=self._Item(key,value)
        self._data.append(node)
        self._upheap(len(self._data)-1)
    def min(self):
        if self.is_empty():
            raise Empty('Priority queue is empty')
        item=self._data[0]
        return (item._key,item._value)
    def remove_min(self):
        if self.is_empty():
            raise Empty('Priority queue is empty')
        self._swap(0, len(self._data) - 1)
        item=self._data.pop()
        self._downheap(0)
        return (item._key,item._value)
HPQ=HeapPriorityQueue()
HPQ.add(10,2)
HPQ.add(9,2)
HPQ.add(5,3)
HPQ.add(8,7)
HPQ.add(1,3)
print(HPQ.min())
print(HPQ.remove_min())
print(HPQ.remove_min())
print(HPQ.remove_min())

基于堆的优先级队列的分析

操作未排序列表
LenO(1)
is_emptyO(1)
addO(logn)
minO(1)
remove_minO(logn)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值