python实现优先队列(一)

学习了堆排序,使用python实现了一个优先队列结构,记录一下实现过程:

用一个python的list来表示堆结构,将list作为参数传入构造函数中,然后在构造函数中建堆:

class prioQueue:
    def __init__(self, elist=[]):
        self._elems = list(elist)
        if elist:
            self.buildheap()

堆一般都是一个完全二叉树,那么根据完全二叉树的性质,一个节点i的左子节点为i+1,右子节点为i*2+1,以最小堆为例,根节点一定是最小值,优先队列必须保证每次弹出的值都是最小的。建堆过程是一个递归的过程,首先拿出list中第一个元素,一个元素必然是一个堆,接下来从list最后拿2个元素分别作为2个子堆,若要将第一个元素这个堆和最后2个元素所构成的子堆合并成一个堆,那么就要保证堆顶的值最小,先判断左右2个子堆的大小,然后用第一个元素和较小的比较,若小,则不变,若大,则将元素与子堆那个元素调换位置,这样就形成了1个3个元素的最小堆,之后再从list中拿出第二个元素,从排序好的堆中一次进行这个步骤,若较小,则跳出循环拿出下一个元素,若较大则交换2个比较的元素,再用这个元素与2个子节点的元素进行比较,直到遍历了整个二叉树都没有更大的元素,那么这个元素就将放在元素的最末尾。这便是一个从堆顶即二叉树根节点开始向下扫描的过程,先定义这个siftDown方法:

def siftdown(self, e,begin, end):
        elems, i, j, = self._elems, begin , begin*2+1

e为要排序的元素,变量i 储存我们开始排序的位置,为了不浪费空间,begin参数来作为排序好及位排好的元素list中的索引,所以一开始是0之后递增,end参数代表着堆元素的个数,也就是len(list)。

然后我们用elems变量保存数组 i作为排序元素的指针 j为i的左子树 进行循环。只要j没有到最后就循环下去。

while j < end:

然后先比较左右子树,使用较小的子树来和插入的e做比较,若e小于它那么就找到位置,否则调换位置继续与换位置后的左右子树进行比较,i位置即是元素e所在的位置:

if j+1<end and elems[j+1] < elems[j]:
                j = j + 1         
            if e < elems[j]:
                break
            elems[i] = elems[j]
            i, j = j , 2*j+1
        elems[i] = e

对list的每一个元素都进行这样的一个向下扫描,就可以完成一个建堆的过程,得到一个最小堆:

    def buildheap(self):
        end = len(self._elems)
        for i in range(end//2,-1,-1):
            self.siftdown(self._elems[i],i,end)
        return self._elems

 

转载于:https://www.cnblogs.com/goddessofpom/p/5596540.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值