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
时间: 2024-10-19 14:19:17

python实现优先队列(一)的相关文章

python实现优先队列(二)

堆建好之后,我们只需要返回数组的第一个元素,即能取到最小值 def peek(self): return self._elems[0] 之后就需要做插入元素和删除元素的操作了. 删除元素和建堆过程有点类似,先从堆顶弹出要删除的元素,然后将最后一个元素拿出来,重新进行建堆,就可以得到一个新的最小堆了: def dequeue(self): elems = self._elems e0 = elems[0] e = elems.pop() if len(elems) > 0: self.siftdo

数据结构:优先队列 基于list实现(python版)

1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 #Author: Minion-Xu 5 #list实现优先队列 6 7 class ListPriQueueValueError(ValueError): 8 pass 9 10 class List_Pri_Queue(object): 11 def __init__(self, elems = []): 12 self._elems = list(elems) 13 #从大到小排序,末

Python中heapq与优先队列【详细】

本文始发于个人公众号:TechFlow, 原创不易,求个关注 今天的文章来介绍Python当中一个蛮有用的库--heapq. heapq的全写是heap queue,是堆队列的意思.这里的堆和队列都是数据结构,在后序的文章当中我们会详细介绍,今天只介绍heapq的用法,如果不了解heap和queue原理的同学可以忽略,我们并不会深入太多,会在之后的文章里详细阐述. 在介绍用法之前,我们需要先知道优先队列的定义.队列大家应该都不陌生,也是非常基础简单的数据结构.我们可以想象成队列里的所有元素排成一

数据结构:优先队列 基于堆实现(python版)

1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 class PrioQueueError(ValueError): 5 pass 6 7 class PrioQueue(object): 8 def __init__(self, elist = []): 9 self._elems = list(elist) 10 if elist: 11 self.buildheap() 12 13 def is_empty(self): 14 ret

Python 使用list实现无边际优先队列 (基于class, 包含迭代器)

#!/usr/bin/python # -*- coding: utf-8 -*- ''' Created on 2015-2-4 @author: beyondzhou @name: test_listpriorityqueue.py ''' def test_listpriorityqueue(): # import pyListQueue from myqueue import ListPriorityQueue print '#Init a queue named smith using

Python 使用由单链表构建的数组实现有边际优先队列 (基于class, 包含迭代器)

#!/usr/bin/python # -*- coding: utf-8 -*- ''' Created on 2015-2-6 @author: beyondzhou @name: test_bpriorityqueue.py ''' def test_bpriorityqueue(): # import pyListQueue from myqueue import BPriorityQueue print '#Init a queue named smith using enqueue'

飘逸的python - 实现一个极简的优先队列

一个队列至少满足2个方法,put和get. 借助最小堆来实现. 这里按"值越大优先级越高"的顺序. #coding=utf-8 from heapq import heappush, heappop class PriorityQueue: def __init__(self): self._queue = [] def put(self, item, priority): heappush(self._queue, (-priority, item)) def get(self):

教你分分钟学会用python爬虫框架Scrapy爬取心目中的女神

欢迎加入Python学习交流群:535993938  禁止闲聊 ! 名额有限 ! 非喜勿进 ! 本博文将带领你从入门到精通爬虫框架Scrapy,最终具备爬取任何网页的数据的能力.本文以校花网为例进行爬取,校花网:http://www.xiaohuar.com/,让你体验爬取校花的成就感. Scrapy,Python开发的一个快速,高层次的屏幕抓取和web抓取框架,用于抓取web站点并从页面中提取结构化的数据.Scrapy用途广泛,可以用于数据挖掘.监测和自动化测试. Scrapy吸引人的地方在于

Python爬虫进阶一之爬虫框架概述

综述 爬虫入门之后,我们有两条路可以走. 一个是继续深入学习,以及关于设计模式的一些知识,强化Python相关知识,自己动手造轮子,继续为自己的爬虫增加分布式,多线程等功能扩展.另一条路便是学习一些优秀的框架,先把这些框架用熟,可以确保能够应付一些基本的爬虫任务,也就是所谓的解决温饱问题,然后再深入学习它的源码等知识,进一步强化. 就个人而言,前一种方法其实就是自己动手造轮子,前人其实已经有了一些比较好的框架,可以直接拿来用,但是为了自己能够研究得更加深入和对爬虫有更全面的了解,自己动手去多做.