精华内容
下载资源
问答
  • 什么是Java优先级队列(Priority Queue)?
    2021-03-07 14:18:52

    39

    优先级队列中的元素可以按照任意的顺序插入,却总是按照排序的顺序进行检索。无论何时调用remove方法,总会获得当前优先级队列中的最小元素,但并不是对所有元素都排序。它是采用了堆(一个可以自我调整的二叉树),执行增加删除操作后,可以让最小元素移动到根。

    发表于 2015-12-03 17:06:15

    回复(5)

    26

    PriorityQueue

    是从

    JDK1.5

    开始提供的新的数据结构接口,它是一种基于优先级堆的极大优先级队列。优先级队列是不同于先进先出队列的另一种队列。每次从队列中取出的是具有最高优先权的元素。如果不提供

    Comparator

    的话,优先队列中元素默认按自然顺序排列,也就是数字默认是小的在队列头,字符串则按字典序排列(参阅

    Comparable

    ),也可以根据

    Comparator

    来指定,这取决于使用哪种构造方法。优先级队列不允许

    null

    元素。依靠自然排序的优先级队列还不允许插入不可比较的对象(这样做可能导致

    ClassCastException

    )

    优先级队列是***的,但是有一个内部容量,控制着用于存储队列元素的数组大小。它通常至少等于队列的大小。随着不断向优先级队列添加元素,其容量会自动增加。无需指定容量增加策略的细节。

    最后,

    PriorityQueue

    不是线程安全的,入队和出队的时间复杂度是

    O(log(n))

    发表于 2017-02-26 16:11:57

    回复(0)

    16

    注意:这里的优先级队列不是数据结构中的概念,而是java中的集合类。

    注意:建议先把我博客里的堆,比较器这两篇文章看一哈

    优先级队列的定义 优先级队列是逻辑结构是小根堆,存储结构是动态数组(到达上限,容量自动加一)的集合类。

    优先级队列的特点 优先级队列里的元素必须有优先级!!!优先级是前后排序的“规则”,也就是说插入队列的类必须实现内部比较器或拥有外部比较器(在构造函数中当参数)!!!!

    优先级队列的拥有小根堆的所有特性。

    优先级队列不是线程安全的。

    优先级队列不允许使用null元素。

    优先级队列本身并一个有序(从a[0]-a[n]全部升序)序列,只有当你把元素一个个取出的时候,这些取出的元素所排成的序列才是有序序列。原因很简单,优先级队列是一个小根堆,也就是只能保证根节点(a[0])是最小的,其余元素的顺序不能保证(当然,其他元素必须遵守小根堆的特性),当我们取出元素(poll)时,我们只能取出根节点的元素,然后把堆的最后一个元素剪切到根节点(这种取出方式是底层算法规定的,充分利用了堆的特性),然后对所有剩余元素进行建堆,建堆之后根节点元素还是最小的(初始堆中的第二小)。由此特点,我们可以引出另外两个知识点:①优先级队列的迭代器遍历出来的数组是没有排序的,只是个小根堆。②如果我们想得到有序的堆,需要把堆先转为数组,然后arrays.sort(queue.toarray),arrays.sort(queue.toarray,comparator对象)或者其他sort方法。

    优先级队列(堆)中的插入就只能插到最后,也就是说添加和插入一个意思;删除也只能删第一个。

    注:每个元素的优先级根据问题的要求而定。当从优先级队列中取出一个元素后,可能出现多个元素具有相同的优先权。在这种情况下,把这些具有相同优先权的元素视为一个先来先服务的队列,按他们的入队顺序进行先后处理。

    常用方法:

    添加(插入):

    publicbooleanadd(E e)

    查看(只返回根节点元素,不删除):

    publicEpeek()

    取出(返回根节点元素,会删除源数据):

    publicEpoll()

    删除(如果有多个相同元素,只会删除第一个):

    publicbooleanremove(Object o)

    还有就是一些collection类通有的方法,不多说了

    记住!!!所有会破坏堆的特性的方法(比如插入删除等)的源码里最后都会加一个建堆方法(siftUp(i,e),也可以说交换方法,调整方法),使队列保持堆的特性

    感谢几位大佬,想了解更多源码,例子,实例图的可以去看看:

    发表于 2018-05-26 16:59:59

    回复(2)

    3

    优先级队列 1.基于优先级堆 2.不允许null值 3.线程不安全 4.出入队时间复杂度O(log(n)) 5.调用remove()返回堆内最小值

    编辑于 2019-05-08 10:47:00

    回复(0)

    3

    理解优先队列的概念以及实现就好了(最大堆、最小堆)

    两个重要操作:每次插入一个元素、每次返回队列中元素的最值

    发表于 2017-08-18 20:09:41

    回复(0)

    5

    PriorityQueue是个基于优先级堆的极大优先级队列。

    此队列按照在构造时所指定的顺序对元素排序,既可以根据元素的自然顺序来指定排序(参阅 Comparable),

    也可以根据 Comparator

    来指定,这取决于使用哪种构造方法。优先级队列不允许 null 元素。

    依靠自然排序的优先级队列还不允许插入不可比较的对象(这样做可能导致

    ClassCastException)

    队列检索操作 poll、remove、peek 和 element

    访问处于队列头的元素。

    优先级队列是***的,但是有一个内部容量,控制着用于存储队列元素的数组的大小。

    它总是至少与队列的大小相同。随着不断向优先级队列添加元素,其容量会自动增加。无需指定容量增加策略的细节。

    注意1:该队列是用数组实现,但是数组大小可以动态增加,容量无限。

    注意2:此实现不是同步的。不是线程安全的。如果多个线程中的任意线程从结构上修改了列表,

    则这些线程不应同时访问 PriorityQueue 实例,这时请使用线程安全的PriorityBlockingQueue 类。

    注意3:不允许使用 null 元素。

    注意4:此实现为插入方法(offer、poll、remove() 和 add 方法)提供

    O(log(n))时间;

    为 remove(Object) 和 contains(Object) 方法提供线性时间;

    为检索方法(peek、element 和 size)提供固定时间。

    注意5:方法iterator()中提供的迭代器并不保证以有序的方式遍历优先级队列中的元素。

    至于原因可参考下面关于PriorityQueue的内部实现

    如果需要按顺序遍历,请考虑使用 Arrays.sort(pq.toArray())。

    注意6:可以在构造函数中指定如何排序。如:

    PriorityQueue()

    使用默认的初始容量(11)创建一个 PriorityQueue,并根据其自然顺序来排序其元素(使用 Comparable)。

    PriorityQueue(int initialCapacity)

    使用指定的初始容量创建一个 PriorityQueue,并根据其自然顺序来排序其元素(使用 Comparable)。

    PriorityQueue(int initialCapacity, Comparator comparator)

    使用指定的初始容量创建一个 PriorityQueue,并根据指定的比较器comparator来排序其元素。

    注意7:此类及其迭代器实现了 Collection 和 Iterator 接口的所有可选 方法。

    PriorityQueue的内部实现

    PriorityQueue对元素采用的是堆排序,头是按指定排序方式的最小元素。堆排序只能保证根是最大(最小),整个堆并不是有序的。

    方法iterator()中提供的迭代器可能只是对整个数组的依次遍历。也就只能保证数组的第一个元素是最小的。

    发表于 2017-03-27 14:20:21

    回复(0)

    1

    PriorityQueue会对入队的元素进行排序,所以在队列顶端的总是最小的元素,但是队列中不是所有元素都是有序的。这个是根据下面的函数有关的

    private void siftUpComparable(int k, E x) {

    Comparable super E> key = (Comparable super E>) x;

    while (k > 0) {

    int parent = (k - 1) >>> 1;

    Object e = queue[parent];

    if (key.compareTo((E) e) >= 0)

    break;

    queue[k] = e;

    k = parent;

    }

    queue[k] = key;

    }

    每次元素插入的位置(为k),就是队列的下标,根据下标找到父节点进行比较,如此循环,直到保证根节点最小就行,所以队列中不是所有的

    元素都是有序的。例如:d,a,f,e,b入列后对应的queue[0] = a、queue[1] = b、queue[2] =

    f、queue[3] = e、queue[4] = d。

    发表于 2017-06-09 16:44:59

    回复(0)

    0

    优先队列底层采用小根堆的逻辑结构,动态数组的数据结构。 优先队列的元素必须有优先级,期货的优先级的方式可以实现comparable接口,或通过策略模式引入competitor,因此null元素,进入优先队列中。 在优先队列中元素本身是处于一个无序的状态。因此,通过迭代器进行遍历时优先对列无序的。只有从优先队列中弹出时,才能产生有序的数组。

    发表于 2020-12-15 11:26:09

    回复(0)

    0

    优先级队列 1.基于优先级堆 2.不允许null值 3.线程不安全 4.出入队时间复杂度O(log(n)) 5.调用remove()返回堆内最小值

    发表于 2020-06-05 01:19:08

    回复(0)

    0

    是一个基于优先级堆的队列,存储的元素必须可比较的。非线性安全,时间复杂度为log(n)

    发表于 2020-02-29 21:27:36

    回复(0)

    0

    PriorityQueue是一个基于优先级堆的***队列,它的元素是按照自然顺序(natural order)排序的。在创建的时候,我们可以给它提供一个负责给元素排序的比较器。PriorityQueue不允许null值,因为他们没有自然顺序,或者说他们没有任何的相关联的比较器。最后,PriorityQueue不是线程安全的,入队和出队的时间复杂度是O(log(n))

    发表于 2019-04-30 22:25:59

    回复(0)

    0

    PriorityQueue是一个基于优先级堆的***队列,它的元素是按照自然顺序(natural order)排序的。在创建的时候,我们可以给它提供一个负责给元素排序的比较器。PriorityQueue不允许null值,因为他们没有自然顺序,或者说他们没有任何的相关联的比较器。最后,PriorityQueue不是线程安全的,入队和出队的时间复杂度是O(log(n))。

    发表于 2019-04-28 16:32:34

    回复(0)

    0

    PriorityQueue是一个基于优先级堆的***队列,它的元素是按照自然顺序(natural order)排序的。在创建的时候,我们可以给它提供一个负责给元素排序的比较器。PriorityQueue不允许null值,因为他们没有自然顺序,或者说他们没有任何的相关联的比较器。最后,PriorityQueue不是线程安全的,入队和出队的时间复杂度是O(log(n))。

    发表于 2019-04-27 20:53:28

    回复(0)

    0

    priortyQueue是一个基于优先级堆的***队列 元素是按自然顺序排序的 不允许null值 他不是线程安全

    发表于 2019-04-26 22:18:02

    回复(0)

    0

    PriorityQueue是一个基于优先级堆的***队列,它的元素是按照自然顺序(natural order)排序的。在创建的时候,我们可以给它提供一个负责给元素排序的比较器。PriorityQueue不允许null值,因为他们没有自然顺序,或者说他们没有任何的相关联的比较器。最后,PriorityQueue不是线程安全的,入队和出队的时间复杂度是O(log(n))。

    发表于 2019-04-25 18:36:32

    回复(0)

    0

    PriorityQueue是一个基于优先级堆的***队列,它的元素是按照自然顺序(natural order)排序的。在创建的时候,我们可以给它提供一个负责给元素排序的比较器。PriorityQueue不允许null值,因为他们没有自然顺序,或者说他们没有任何的相关联的比较器。

    发表于 2018-09-21 23:10:03

    回复(0)

    0

    PriorityQueue是一个基于优先级堆的***队列,它的元素是按照自然顺序(natural order)排序的。在创建的时候,我们可以给它提供一个负责给元素排序的比较器。PriorityQueue不允许null值,因为他们没有自然顺序,或者说他们没有任何的相关联的比较器。最后,PriorityQueue不是线程安全的,入队和出队的时间复杂度是O(log(n))。

    发表于 2018-09-13 11:40:35

    回复(0)

    0

    priorityQuene是一个基于优先级堆的一个***队列,里面的元素是按照自然顺序进行排列,在创建的时候也可以给它提供一个负责元素排序的比较器。它的元素不能为null值,因为这样就没有自然顺序,或者说就是没有一个对应它的比较器。最后,priorityQuene的不是线程安全的,入队和出队的时间复杂度是n(log n)

    编辑于 2018-05-03 08:49:34

    回复(0)

    0

    PriorityQueue基于优先级堆得极大优先级队列。若不指定元素的排序方式,则以自然顺序排序,也可实现comparator接口进行自定义排序。队列中不允许有null值,底层是数组,但是可动态改变队列的大小。它是线程不安全的,若用于多线程环境使用PriorityBlockQueue.priorityqueue入队和出队的时间是o(logn).

    发表于 2018-03-14 14:30:31

    回复(0)

    更多相关内容
  • 排队 matlab代码
  • 优先级队列

    2018-11-10 21:10:55
    这是数据结构课程中优先级队列这一章的ppt,其中简要介绍了相关知识,希望对大家有所帮助。
  • PriorityQueue-MEX-Matlab 优先级队列 matlab
  • ES6的优先级队列 描述 ES6实现具有TypeScript支持的优先级队列数据结构。 请访问以了解更多有关如何将此文档翻译成更多语言的信息。 内容 安装 纱 yarn add prioqueue NPM npm install prioqueue 深入 优先级队列...
  • 优先级和项目存储在IndexMap中,并且队列被实现为索引堆。 请在这里阅读API文档用法要使用此板条箱,只需在Cargo.toml中添加以下字符串:priority-queue =“ 1.0.0”版本号遵循semver约定。 然后,如以下示例所示,...
  • 下面的类利用 heapq 模块实现了一个简单的优先级队列: import heapq class PriorityQueue: def __init__(self): self._queue = [] self._index = 0 def push(self, item, priority): heapq.heappush(self._...
  • NULL 博文链接:https://yunjiechao-163-com.iteye.com/blog/2405056
  • 那么本文将介绍一下另一种特殊的队列结构,叫做 优先级队列。 上一篇文章的跳转链接—— 公众号:Lpyexplore的编程小屋 关注我,每天更新,带你在python爬虫的过程中学习前端,还有更多电子书和面试题等你来拿 ...

    本系列文章【数据结构与算法】所有完整代码已上传 github,想要完整代码的小伙伴可以直接去那获取,可以的话欢迎点个Star哦~下面放上跳转链接

    上一篇文章讲解了队列的相关知识,同时用代码实现了一个队列结构。那么本文将介绍一下另一种特殊的队列结构,叫做 优先级队列

    上一篇文章的跳转链接——【数据结构与算法】详解什么是队列,并用代码手动实现一个队列结构

    • 公众号:前端印象
    • 不定时有送书活动,记得关注~
    • 关注后回复对应文字领取:【面试题】、【前端必看电子书】、【数据结构与算法完整代码】、【前端技术交流群】

    在这里插入图片描述

    一、什么是优先级队列

    在了解了什么是队列以后,我们再来了解优先级队列,顾名思义,优先级队列就是在队列的基础上给每个元素加上了先后顺序,我们仍然拿排队买票的例子来讲解。

    普通的排队买票队伍就是一个抽象的队列,如图
    在这里插入图片描述
    但是,此时这个买票窗口上贴上了如图上这样几个字
    在这里插入图片描述
    此时,某些排队的人就有了比别人优先买到票的权利了。假设 小人3 是孕妇,那么她可以排到第一个,比 小人4小人8 更早的买到票,而 小人4小人8 都没有特殊身份,但是因为 小人4小人8 来的早,所以 小人4 还是排在 小人8 的前面,此时是这样的
    在这里插入图片描述
    经过这样一个讲解,相信大家都知道 优先级队列 和普通的队列的区别了吧。

    在向优先级队列插入元素时,每个元素有一个自己的号码牌,表示该元素是排在队列的前端还是后端。因此,在优先级队列里,也就没有先进先出这样一个结构特点了。

    假如现在有这样一个空的优先级队列
    在这里插入图片描述
    我们向这个空的优先级队列中插入一个元素 JavaScript,并给它一个号码牌 3,此时是这样的
    在这里插入图片描述
    这时我们再向优先级队列中插入一个元素 python,也给它一个号码牌 1,假设号码牌上的数字越小,在队列中排得越靠前,那么此时是这样的
    在这里插入图片描述
    如果再插入一个元素 Java,给它一个号码牌 7,因为数字 713 都小,所以此时的队列是这样的
    在这里插入图片描述
    好了,对 优先级队列 的讲解就讲到这里,如果还有不明白,欢迎关注文章开头的公众号私聊我或者在本文底下留言评论,我看到会解答。

    接下来我们就来讲解一下 优先级队列 常用的一些方法吧~

    二、优先级队列的方法

    其实优先级队列的方法跟普通队列的方法一模一样,也无非是数据的插入 、删除 、查询等方法,只不过这两者的方法内部实现逻辑有略微的区别,前者比较复杂。

    老样子,我们还是先列举一下,优先级队列的方法,如下表

    方法含义
    enqueue()向队列添加元素
    dequeue()删除队列最前端的一个元素,并返回该元素
    front()返回队列前端的元素,但不会移除该元素
    isEmpty()查看队列是否为空
    size()返回队列内元素的个数
    toString()以字符串的形式展示队列内的所有元素

    三、用代码实现优先级队列

    接下来,我们也还是用JavaScript实现一个基于数组的线性结构的类,因为是基于数组实现的队列,所以我们可以把数组的头部看作是队列的前端,把数组的尾部看作是队列的后端。这里我们规定数字越小的优先级越大

    (1)创建一个构造函数

    function PriorityQueue() {
    	//属性
        this.list = []
    }
    

    (2)创建内部构造函数

    这一步还是挺有趣的,我们准备在刚才创建的构造函数的内部再创建一个构造函数,为什么要这么做呢?因为上面讲过,在优先级队列中存储的元素都具有两个值,分别是 存入的数据号码牌(优先级),所以我们准备创建一个这样的构造函数,来存储这两个值,之后需要插入一个元素时,就可以直接 new 一个实例对象出来。

    function PriorityQueue() {
    	//属性
        this.list = []
    	
    	//创建内部构造函数,存储元素的数据和优先级
    	function EachElement(e, num) {
            this.element = e
            this.priority = num
        }
    }
    

    (3)实现enqueue()方法

    因为优先级队列的方法实现会比普通队列的方法复杂一点,我会讲解一下每个方法的实现思路,方便大家理解。

    enqueue()方法就是向优先级队列添加一个元素,并自动根据每个元素的优先级插入到合适的位置。

    方法实现思路:

    1. 先创建一个新元素的实例对象,将元素的值和优先级传给该实例对象
    2. 先判断队列是否为空。若为空,则直接想队列添加该元素
    3. 队列不为空,则从头遍历整个队列,判断我们要添加的元素与队列中的元素哪个优先级更大,然后在合适的位置插入元素
    4. 若我们要添加的元素比当前队列中所有元素的优先级都要小,那么直接在队列后端添加该元素

    思路讲完了,我们直接来看代码

    function PriorityQueue() {
    	//属性
        this.list = []
    	
    	//创建内部构造函数,存储元素的数据和优先级
    	function EachElement(e, num) {
            this.element = e
            this.priority = num
        }
    
    	//向队列添加元素
        PriorityQueue.prototype.enqueue = function (e, priority) {
        	// 1.创建新元素的实例对象
            let element = new EachElement(e, priority)
            
    		// 2.判断队列是否为空
            if(this.list.length === 0) {
                this.list.push(element)
                return;
            }
            
            // 3.队列不为空,遍历整个队列,比较优先级大小
            for(let i in this.list) {
                if(element.priority < this.list[i].priority) {
                    this.list.splice(i, 0, element)
                    return;
                }
            }
            
            // 4.新元素优先级最小,直接添加到队列的后端
            this.list.push(element)
        }
    }
    

    我们来使用一下该方法

    let pq = new PriorityQueue()
    
    pq.enqueue('abc', 10)
    pq.enqueue('abb', 1)
    pq.enqueue('cdf', 9)
    

    此时的优先级队列是这样的
    在这里插入图片描述
    在上面的基础上,我们再向优先级队列添加一个元素 eee,并赋予优先级 9,即 pq.enqueue('eee', 9)。我们看看此时的优先级是什么样的
    在这里插入图片描述
    可以看到,同样的优先级都为9,但我们后添加的元素 eee 却排在了先添加的元素 cdf 的后面。我们想一下,排队买票,那些有特殊身份的人有权利比我们普通人先买到票,那很正常,但是那些没有特殊身份的普通人都是平等的(优先级相同),那必须得遵守个先来后到了,所以当优先级相同时,先添加的元素永远比后添加的元素靠前。

    (4)实现dequeue()方法

    dequeue()方法就跟普通队列一样啦,直接删除队列前端的第一个元素即可。

    接下来我们来单独实现一下该方法

    function PriorityQueue() {
    	//属性
        this.list = []
    	
    	//创建内部构造函数,存储元素的数据和优先级
    	function EachElement(e, num) {
            this.element = e
            this.priority = num
        }
    
    	//出列
    	PriorityQueue.prototype.dequeue = function () {
            return this.list.shift()
        }
    }
    

    我们来使用一下该方法

    let pq = new PriorityQueue()
    
    //先添加三个元素
    pq.enqueue('abc', 10)
    pq.enqueue('abb', 1)
    pq.enqueue('cdf', 9)
    
    pq.dequeue()              // 返回值为abb的元素实例对象
    

    此时的优先级队列是这样的
    在这里插入图片描述

    (5)实现front()方法

    front()方法就是获取当前优先级队列前端第一个元素,但不会删除该元素。这个方法也没什么好说的,跟普通队列的方法一样。

    接下来我们来单独实现一下该方法

    function PriorityQueue() {
    	//属性
        this.list = []
    	
    	//创建内部构造函数,存储元素的数据和优先级
    	function EachElement(e, num) {
            this.element = e
            this.priority = num
        }
    
    	//返回优先级队列第一个元素
        PriorityQueue.prototype.front = function () {
            return this.list[0]
        }
    }
    

    我们来使用一下该方法

    let pq = new PriorityQueue()
    
    //先添加三个元素
    pq.enqueue('abc', 10)
    pq.enqueue('abb', 1)
    pq.enqueue('cdf', 9)
    
    pq.front()              // 返回值为abb的元素实例对象
    

    dequeue()方法有区别,front()并没有删除前端的第一个元素,所以此时的优先级队列仍然是这样的
    在这里插入图片描述

    (6)实现isEmpty()方法

    isEmpty()方法是判断优先级队列里是否有元素,即是否为空。实现原理很简单,判断数组长度是否为0就可以了。

    接下来我们来单独实现一下该方法

    function PriorityQueue() {
    	//属性
        this.list = []
    	
    	//创建内部构造函数,存储元素的数据和优先级
    	function EachElement(e, num) {
            this.element = e
            this.priority = num
        }
    
        //判断优先级队列是否为空
        PriorityQueue.prototype.isEmpty = function() {
            if(this.list.length === 0) {
                return true
            }
            else {
                return false
            }
        }
    }
    

    我们来使用一下该方法

    let pq = new PriorityQueue()
    
    pq.isEmpty()            //返回 true,因为此时没有添加元素
    
    //先添加三个元素
    pq.enqueue('abc', 10)
    pq.enqueue('abb', 1)
    pq.enqueue('cdf', 9)
    
    pq.isEmpty()            //返回 false,因为此时优先级队列内有三个元素
    

    (7)实现size()方法

    size()方法就是判断优先级队列中的元素个数。实现方式也很简单,直接返回数组长度即可。

    接下来我们来单独实现一下该方法

    function PriorityQueue() {
    	//属性
        this.list = []
    	
    	//创建内部构造函数,存储元素的数据和优先级
    	function EachElement(e, num) {
            this.element = e
            this.priority = num
        }
    
        //返回优先级队列的元素个数
        PriorityQueue.prototype.size = function () {
            return this.list.length
        }
    }
    

    我们来使用一下该方法

    let pq= new PriorityQueue()
    
    pq.size()     //返回 0,因为还未向优先级队列添加过元素
    
    //添加三个元素
    pq.enqueue('abc', 10)
    pq.enqueue('abb', 1)
    pq.enqueue('cdf', 9)
    
    pq.size()     //返回 3,因为上面三行代码分别向优先级队列添加了一个元素
    

    (8)实现toString()方法

    toString()方法就是将优先级队列内的元素用字符串的方式展示出来(将数组转化成字符串)并返回,与普通队列的 toString()方法不同的是,它不仅会将元素的值展示出来,还会展示每个元素的优先级。

    接下来我们来单独实现一下该方法

    function PriorityQueue() {
    	//属性
        this.list = []
    	
    	//创建内部构造函数,存储元素的数据和优先级
    	function EachElement(e, num) {
            this.element = e
            this.priority = num
        }
    
        //返回当前优先级队列
        PriorityQueue.prototype.toString = function () {
            let string = ''
            for(let i in this.list) {
                string += `${this.list[i].element}:${this.list[i].priority} `
            }
            return string
        }
    }
    

    我们来使用一下该方法

    let pq= new PriorityQueue()
    
    pq.enqueue('abc', 10)
    pq.enqueue('abb', 1)
    pq.enqueue('cdf', 9)
    
    pq.toString()     //返回  abb:1 cdf:9 abc:10
    

    四、优先级队列的补充

    本文我们是用数组来实现优先级队列的,但你们有没有发现,当我们每次添加元素时,都需要与优先级队列中的很多元素比较优先级大小,然后再找到一个合适的位置插入元素。因为是以数组形式实现的,所以在该优先级队列里,每一个元素都有自己的下标值,并且我们可以通过下标值直接获取到它。

    如下图,现在有一个这样的优先级队列,并且它们的下标值也标在下面
    在这里插入图片描述
    然后此时我们准备添加一个值为 c#,优先级为 2 的元素,那么我们通过遍历队列元素比较优先级发现,应该在下标值为 1 的位置插入元素,所以,原本优先级队列中下标值为 1 以及之后的所有元素都要向后移动一个位置,即下标值 +1,结果如下图
    在这里插入图片描述
    因为这个例子中,添加一个元素,要改动 n-1 个元素的下标值,可想而知,这是一个非常消耗性能的操作,所以在这里用 数组 来实现优先级队列还是有点不合适。

    下一篇文章我会开始讲 链表 ,这种数据结构相对于数组的优势就在于往结构中插入元素性能比较高,不会牵一发而动全身。所以等到之后大家学习了链表,可以回过头来用链表实现一下优先级队列。

    五、总结

    优先级队列结构的讲解就到这里了,希望大家对优先级队列有了更深一层的理解。下一篇文章我将讲解一下链表

    大家可以关注我,之后我还会一直更新别的数据结构与算法的文章来供大家学习,并且我会把这些文章放到【数据结构与算法】这个专栏里,供大家学习使用。

    然后大家可以关注一下我的微信公众号:前端印象,等这个专栏的文章完结以后,我会把每种数据结构和算法的笔记放到公众号上,大家可以去那获取。

    或者也可以去我的github上获取完整代码,欢迎大家点个Star

    我是Lpyexplore,创作不易,喜欢的加个关注,点个收藏,给个赞~ 带你们在Python爬虫的过程中学习Web前端

    展开全文
  • Java优先级队列PriorityQueue

    千次阅读 2021-10-29 18:05:16
    目录普通队列对比优先级队列:逆序优先级队列自定义优先级队列的优先级 相较于普通先进先出队列来说,优先级队列会根据优先级进行由高到低排序,出队时优先级高的先出队。 普通队列对比优先级队列: 1.普通队列: ...

    相较于普通先进先出队列来说,优先级队列会根据优先级进行由高到低排序,出队时优先级高的先出队。

    普通队列对比优先级队列:

    1.普通队列:

    import java.util.LinkedList;
    import java.util.Queue;
    
    public class MainTest {
    public static void main(String[] args) {    
    	    Queue<Integer> queue = new LinkedList<>();
            queue.offer(0);
            queue.offer(2);
            queue.offer(5);
            queue.offer(3);
            queue.offer(6);
            queue.offer(1);
            queue.offer(4);
            queue.offer(0);
    
            System.out.println(queue.poll());
            System.out.println(queue.poll());
            System.out.println(queue.poll());
            System.out.println(queue.poll());
            System.out.println(queue.poll());
            System.out.println(queue.poll());
            System.out.println(queue.poll());
            System.out.println(queue.poll());
    	}
    }
    

    输出:

    0
    2
    5
    3
    6
    1
    4
    0
    

    2.优先级队列:

    import java.util.PriorityQueue;
    import java.util.Queue;
    
    public class MainTest {
    public static void main(String[] args) {   
            Queue<Integer> p = new PriorityQueue<>();
            p.offer(0);
            p.offer(2);
            p.offer(5);
            p.offer(3);
            p.offer(6);
            p.offer(1);
            p.offer(4);
            p.offer(0);
    
            System.out.println(p.poll());
            System.out.println(p.poll());
            System.out.println(p.poll());
            System.out.println(p.poll());
            System.out.println(p.poll());
            System.out.println(p.poll());
            System.out.println(p.poll());
            System.out.println(p.poll());
       }
    }
    

    输出:

    0
    0
    1
    2
    3
    4
    5
    6
    

    总结:
    1.普通优先级队列先进先出。优先级队列会根据优先级进行排序,优先级高的先出队;
    2.对于数字类型的优先级队列,默认数字越小优先级越高;
    3.对于字符串类型的优先级对列,默认安照ASCII码位置,位置越小优先级越高,即优先级:字符0到9 >大写字符A到Z > 小写字符a到z 如果字符串首字符一样则依次比较后面的字符判断优先级。

    逆序优先级队列

    默认的数字类型优先级队列数字越小优先级越高,字符串类型的优先级对列ASCII码位置越小优先级越高。有时候我们需要数字越大优先级越高或者ASCII码位置越大优先级越高,所以需要改变默认的优先级。

    逆序优先级队列:

    import java.util.PriorityQueue;
    import java.util.Queue;
    
    public class MainTest {
    public static void main(String[] args) {   
            Queue<Integer> p = new PriorityQueue<>(Collections.reverseOrder());
            p.offer(0);
            p.offer(2);
            p.offer(5);
            p.offer(3);
            p.offer(6);
            p.offer(1);
            p.offer(4);
            p.offer(0);
    
            System.out.println(p.poll());
            System.out.println(p.poll());
            System.out.println(p.poll());
            System.out.println(p.poll());
            System.out.println(p.poll());
            System.out.println(p.poll());
            System.out.println(p.poll());
            System.out.println(p.poll());
       }
    }
    

    输出:

    6
    5
    4
    3
    2
    1
    0
    0
    

    自定义优先级队列的优先级

    优先级队列里根据每个学生的平均分降序排序,即平均分越高优先级越高,越先出队列

    学生类Student:

    import java.util.List;
    
    public class Student  {
    
        public String name;//姓名
        public List<Integer> score;//分数
    
        public Student (String name ,List<Integer> score){
            this.name=name;
            this.score=score;
        }
    
        public Student (){}
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public List<Integer> getScore() {
            return score;
        }
    
        public void setScore(List<Integer> score) {
            this.score = score;
        }
    
        @Override
        public String toString() {
            int avg= score.stream().reduce(0, Integer::sum)/score.size();
            return "name:"+name+",score:"+score+",平均分:"+avg;
        }
    }
    

    测试:

    import java.util.PriorityQueue;
    import java.util.Queue;
    
    public class MainTest {
    public static void main(String[] args) {   
            Student student1 = new Student("小明", Arrays.asList(77, 56, 98));
            Student student2 = new Student("小王", Arrays.asList(95, 62, 80));
            Student student3 = new Student("小红", Arrays.asList(82, 69, 73));
            Student student4 = new Student("小刘", Arrays.asList(90, 86, 74));
    
            Queue<Student> q = new PriorityQueue<>((a, b) -> {
                //计算每个学生分数的平均分,降序排序(即平均分越高优先级越高,越先出队列)
                List<Integer> lisaA = a.getScore();
                List<Integer> lisaB = b.getScore();
                int avgA = lisaA.stream().reduce(0, Integer::sum) / lisaA.size();
                int avgB = lisaB.stream().reduce(0, Integer::sum) / lisaB.size();
                return avgB - avgA;
            });
    
            q.offer(student1);
            q.offer(student2);
            q.offer(student3);
            q.offer(student4);
    
            System.out.println(q.poll().toString());
            System.out.println(q.poll().toString());
            System.out.println(q.poll().toString());
            System.out.println(q.poll().toString());
        }
    }
    

    输出:

    name:小刘,score:[90, 86, 74],平均分:83
    name:小王,score:[95, 62, 80],平均分:79
    name:小明,score:[77, 56, 98],平均分:77
    name:小红,score:[82, 69, 73],平均分:74
    

    参考:Priority Queue in Reverse Order in Java

    展开全文
  • c语言中优先级队列A Priority Queue is a variant of a Queue such that it’s elements are ordered based on their priority. C++ has a built-in priority queue data structure in it’s Standard Template ...

    c语言中优先级队列

    A Priority Queue is a variant of a Queue such that it’s elements are ordered based on their priority. C++ has a built-in priority queue data structure in it’s Standard Template Library (STL).

    优先级队列队列的一种变体,可以根据其优先级对元素进行排序。 C ++在其标准模板库( STL )中具有内置的优先级队列数据结构。

    Priority queues are implemented as container adapters in C++.

    优先级队列在C ++中作为容器适配器实现。

    This means that like other container adapters, they have member functions for the container objects.

    这意味着像其他容器适配器一样,它们具有容器对象的成员功能。

    Let’s understand how we can use the Priority Queue container in C++ to make our own priority queues.

    让我们了解如何使用C ++中的Priority Queue容器创建自己的优先级队列。



    创建一个优先队列 (Create a Priority Queue)

    We can create a priority queue by declaring a priority queue variable of the type std::priority_queue<type>.

    我们可以通过声明类型为std::priority_queue<type>的优先级队列变量来创建优先级队列。

    The std:: namespace signifies that this supports STL (Standard Template Library) operations.

    std::名称空间表示它支持STL (标准模板库)操作。

    NOTE: To use this, we must include the <queue> header file in our program.

    注意 :要使用此功能,我们必须在程序中包含<queue>头文件。

    Since this is a container of the STL, we must provide the template type for the queue. It could be anything from int, float, char, string, etc.

    由于这是STL的容器,因此我们必须提供队列的模板类型。 它可以是intfloatcharstring等任何东西。

    For example, the following are valid declarations of a priority queue.

    例如,以下是优先级队列的有效声明。

    
    #include <queue>
    #include <string>
    
    std::priority_queue<int> pq1;
    std::priority_queue<float> pq2;
    std::priority_queue<std::string> pq3;
    

    优先级队列上的常用方法 (Common Methods on a Priority Queue)

    Some of the methods which the priority queue container supports are namely:

    优先级队列容器支持的一些方法是:

    • empty() -> Checks if the Priority Queue is empty

      empty()->检查优先级队列是否为空
    • size() -> Returns the number of elements in the Queue

      size()->返回队列中的元素数
    • top() -> Returns the element at the top of the Queue

      top()->返回队列顶部的元素
    • push() -> Pushes an element to the bottom of the Queue

      push()->将元素推到队列底部
    • pop() -> Pops the last element from the Queue

      pop()->从队列中弹出最后一个元素

    Let’s understand the above methods using an example. The below code uses all the above methods involving the priority queue.

    让我们通过一个例子来了解上述方法。 下面的代码使用上述所有涉及优先级队列的方法。

    
    #include <iostream>
    #include <string>
    #include <queue>
    
    using namespace std;
    
    void print_pqueue (priority_queue<int> pq) {
        // Prints the Priority Queue
        priority_queue<int> copy_q = pq;
        cout << "Priority Queue : ";
        while (!copy_q.empty()) {
            cout << copy_q.top() << " ";
            copy_q.pop();
        }
        cout << "\n";
    }
    
    int main() {
        // Program demonstrating use of Priority Queue
        // methods
        
        // Create an empty priority queue of integers
        priority_queue<int> queue_int;
    
        // Is the Queue empty now? Yes!
        cout << "Is the Queue empty now? : " << (queue_int.empty() ? "Yes" : "No") << endl;
    
        // Let's add some elements!
        cout << "Adding some elements...\n";
        queue_int.push(100);
        queue_int.push(200);
        queue_int.push(400);
        queue_int.push(50);
    
        cout << "Number of elements : " << queue_int.size() << endl;
        cout << "Top element : " << queue_int.top() << endl << endl;
    
        print_pqueue(queue_int);
    
        cout << "Popping element from the top...\n\n";
        queue_int.pop();
        print_pqueue(queue_int);
        
        return 0;
    }
    
    
    

    Here, we create a priority queue of integers and insert the elements 100, 200, 400 and 50 in order.

    在这里,我们创建一个整数优先级队列,并依次插入元素100、200、400和50。

    Note that since a priority queue has the elements sorted in descending order from the top, the insertion will look like this:

    请注意,由于优先级队列的元素从顶部开始按降序排列,因此插入将如下所示:

    Priority Queue
    Priority Queue
    优先队列

    After pushing to the queue, we pop the topmost element from the Queue, i.e, the element with the highest priority.

    推送到队列后,我们从队列中弹出最上面的元素,即具有最高优先级的元素。

    Therefore, 400 will be popped out, making 200 as the new head of the Queue.

    因此,将弹出400 ,使200作为队列的新头。

    
    Is the Queue empty now? : Yes
    Adding some elements...
    Number of elements : 4
    Top element : 400
    
    Priority Queue : 400 200 100 50 
    Popping element from the top...
    
    Priority Queue : 200 100 50
    

    This shows how we can use the priority queue container easily. Let us move on to a case where you want to have your own priority scheme.

    这显示了我们如何轻松使用优先级队列容器。 让我们继续讨论您想要拥有自己的优先级方案的情况。



    实现我们自己的比较功能 (Implementing our own Comparison function)

    By default, the C++ priority queue evaluates priority only based on sorted values. We can change this, by implementing our own comparison function!

    默认情况下,C ++优先级队列仅根据排序后的值评估优先级。 我们可以通过实现自己的比较功能来改变它!

    We can overload the default comparison function, by overloading the STL comparison operator.

    我们可以通过重载STL 比较运算符来重载默认比较功能。

    For this, we must create a comparison class first. Let us call it CompareClass and then introduce our custom comparison in the operator() block.

    为此,我们必须首先创建一个比较类。 让我们将其CompareClass ,然后在operator()块中引入我们的自定义比较。

    This must return a bool, since this is a comparison function, and must also be public.

    由于这是一个比较函数,因此必须返回bool ,并且还必须是public

    The code structure will look similar to this. We are now comparing based on the ascending order of values!

    代码结构看起来与此类似。 我们现在基于值的升序进行比较!

    
    // Create a Comparison Class for our
    // integer priority queue
    class CompareClass {
        public:
            bool operator() (int a, int b) {
                if (a > b)
                    return true;
                return false;
            }
    };
    
    

    We are still not yet done. We need to make the compiler realize that we are using this new class for our comparison operator.

    我们还没有完成。 我们需要使编译器意识到我们将这个新类用于比较运算符。

    For that, we will need to add two more parameters to our priority_queue<> STL invocation.

    为此,我们将需要在我们的priority_queue<> STL调用中添加两个以上的参数。

    
    priority_queue<type, vector<type>, CompareClass()> pqueue;
    

    The second parameter tells the compiler that the queue is implemented as a vector<type>. The third one is our Comparison Class.

    第二个参数告诉编译器该队列被实现为vector<type> 。 第三个是我们的比较类。

    We will modify our old code to include these new changes.

    我们将修改旧代码以包括这些新更改。

    
    #include <iostream>
    #include <string>
    #include <queue>
    
    using namespace std;
    
    // Create a Comparison Class for our
    // integer priority queue
    class CompareClass {
        public:
            bool operator() (int a, int b) {
                if (a > b)
                    return true;
                return false;
            }
    };
    
    void print_pqueue (priority_queue<int, vector<int>, CompareClass> pq) {
        // Prints the Priority Queue
        priority_queue<int, vector<int>, CompareClass> copy_q = pq;
        cout << "Priority Queue : ";
        while (!copy_q.empty()) {
            cout << copy_q.top() << " ";
            copy_q.pop();
        }
        cout << "\n";
    }
    
    int main() {
        // Program demonstrating use of Priority Queue
        // methods
        
        // Create an empty priority queue of integers
        priority_queue<int, vector<int>, CompareClass> queue_int;
    
        // Is the Queue empty now? Yes!
        cout << "Is the Queue empty now? : " << (queue_int.empty() ? "Yes" : "No") << endl;
    
        // Let's add some elements!
        cout << "Adding some elements...\n";
        queue_int.push(100);
        queue_int.push(200);
        queue_int.push(400);
        queue_int.push(50);
    
        cout << "Number of elements : " << queue_int.size() << endl;
        cout << "Top element : " << queue_int.top() << endl << endl;
    
        print_pqueue(queue_int);
    
        cout << "Popping element from the top...\n\n";
        queue_int.pop();
        print_pqueue(queue_int);
        
        return 0;
    }
    

    Output

    输出量

    
    Is the Queue empty now? : Yes
    Adding some elements...
    Number of elements : 4
    Top element : 50
    
    Priority Queue : 50 100 200 400 
    Popping element from the top...
    
    Priority Queue : 100 200 400 
    

    Observe that we insert elements based on their increasing order of values now, so the top of the queue is the lowest element.

    观察到我们现在根据其值的升序插入元素,因此队列的顶部是最低的元素。

    Thus, we have successfully implemented our own comparison function!

    因此,我们已经成功实现了自己的比较功能!



    结论 (Conclusion)

    In this article, we looked at the C++ Priority Queue container. We also saw some of the methods involved in manipulating them.

    在本文中,我们研究了C ++ Priority Queue容器。 我们还看到了一些操纵它们的方法。

    Recommended Read: Hash Tables in C++

    推荐阅读: C ++中的哈希表



    参考资料 (References)



    翻译自: https://www.journaldev.com/35189/priority-queue-in-c-plus-plus

    c语言中优先级队列

    展开全文
  • Web上有许多优先级队列实现,但是我找不到满足以下条件的任何优先级队列: 在运行时不分配内存 有测试 是功能性的,面向数据的 很小! (〜150行代码) 是一个纯ES模块 所以我们到了! 用法 import PQ from '...
  • 优先级队列是一种队列结构,是0个或多个元素的集合,每个元素都有一个优先权,PriorityQueue被内置于JDK中,本文就来解析Java中PriorityQueue优先级队列结构的源码及用法.
  • NULL 博文链接:https://java--hhf.iteye.com/blog/2163480
  • 使用二进制堆实现的非常快JavaScript优先级队列,而二进制堆又使用两个底层的并行。 完全没有依赖关系; 简直就是香草JS。 它是优先级队列的最快公开可用JavaScript库实现。 这是将Heapify与其他流行库进行比较的...
  • Java 优先级队列

    2022-02-25 20:54:37
    Java 优先级队列
  • 优先级队列一方面可以用来控制流量,同时还可以在资源有限的情况下优先处理高优的流量。本文带你用Go实现从单队列到优先级队列的演进过程
  • 优先级队列(堆)

    千次阅读 2022-01-29 11:44:11
    优先级队列(堆)+TopK
  • Java原型源码数据结构-优先级队列 Java中优先级队列实现的源代码。
  • 数据结构——【优先级队列】详解

    多人点赞 热门讨论 2022-03-09 15:26:18
    目录 一. PriorityQueue PriorityQueue 简介 继承关系 PriorityQueue 示例 ...二....三....四....一....PriorityQueue,即优先级队列优先级队列可以保证每次取出来的元素都是...Java优先级队列默认每次取出来的为最小元素>.
  • 优先级队列的实现

    2021-04-16 15:48:15
    优先级队列(Priority Queue) 优先级队列本身也是一个队列,只不过常规的队列是先进先出,而优先级队列可以插队,即让队列中优先级最高的元素先出队。在Java中,普通队列是由双向链表来实现的,如果优先级队列也...
  • 优先级队列PriorityQueue

    2020-08-11 18:04:35
    在小顶堆或是大顶堆堆操作中经常会用到优先级队列PriorityQueue。网上有篇文章讲的不错,转载一波梭哈。 一、什么是优先级队列 1、概念 我们都知道队列,队列的核心思想就是先进先出,这个优先级队列有点不太一样。...
  • java 队列示例Priority Queues are used very often in real life applications. In this article we will learn what priority queues are and how we can use... 在本文中,我们将学习什么是优先级队列以及如何在J...
  • js 优先级队列

    2022-04-11 15:23:29
    当我们希望某个优先级权重比较高的数据,展现在最前面,插入数据的时候,应该按照优先级高低来排序,js的优先级队列最为合适。 比如有这样一组数据 校长 院长 老师 学生 他们的权重依次为 0 1 2 3,在乱序的情况下...
  • 1. 优先级队列是什么?? 首先,优先级队列是一个队列,队列所有的性质,它也有。 其次,优先级队列每次取出的是优先级最高的元素。 优先级队列的内部是用堆来维护的。将优先级最高的排在前面。 2. 什么时候用这个...
  • 优先级队列的Java实现是一种特殊的队列,其中元素的排序由其自然排序原则确定(默认最小堆),也可以根据创建期间提供的Comparator进行定制。我们在构造过程中调用的构造函数决定要与优先级队列一起使用的排序原则。与...
  • 基于优先级队列方案抵御DDoS攻击,秦琳琳,张永平,本文提出基于优先级队列的自适应调整方案,采用带宽分配策略把合法用户的数据包分配到高优先级队列,恶意或可疑攻击者的数据包分

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 245,041
精华内容 98,016
关键字:

优先级队列

友情链接: UART1.zip