java PriorityQueue

java数据结构PriorityQueue PriorityQueue 是具有优先级别的队列,优先级队列的元素按照它们的自然顺序排序,或者由队列构造时提供的 Comparator 进行排序,这取决于使用的是哪个构造函数。 阅读详情

优先级队列是一种队列结构,是0个或多个元素的集合,每个元素都有一个优先权,PriorityQueue被内置于JDK中,本文就来解析Java中PriorityQueue优先级队列结构的源码及用法.
一、PriorityQueue的数据结构
JDK7中PriorityQueue(优先级队列)的数据结构是二叉堆。准确的说是一个最小堆。
二叉堆是一个特殊的堆, 它近似完全二叉树。二叉堆满足特性:父节点的键值总是保持固定的序关系于任何一个子节点的键值,且每个节点的左子树和右子树都是一个二叉堆。
当父节点的键值总是大于或等于任何一个子节点的键值时为最大堆。 当父节点的键值总是小于或等于任何一个子节点的键值时为最小堆。
下图是一个最大堆
这里写图片描述
priorityQueue队头就是给定顺序的最小元素。
priorityQueue不允许空值且不支持non-comparable的对象。priorityQueue要求使用Comparable和Comparator接口给对象排序,并且在排序时会按照优先级处理其中的元素。
priorityQueue的大小是无限制的(unbounded), 但在创建时可以指定初始大小。当增加队列元素时,队列会自动扩容。
priorityQueue不是线程安全的, 类似的PriorityBlockingQueue是线程安全的。
我们知道队列是遵循先进先出(First-In-First-Out)模式的,但有些时候需要在队列中基于优先级处理对象。举个例子,比方说我们有一个每日交易时段生成股票报告的应用程序,需要处理大量数据并且花费很多处理时间。客户向这个应用程序发送请求时,实际上就进入了队列。我们需要首先处理优先客户再处理普通用户。在这种情况下,Java的PriorityQueue(优先队列)会很有帮助。
PriorityQueue是基于优先堆的一个无界队列,这个优先队列中的元素可以默认自然排序或者通过提供的Comparator(比较器)在队列实例化的时排序。
优先队列不允许空值,而且不支持non-comparable(不可比较)的对象,比如用户自定义的类。优先队列要求使用Java Comparable和Comparator接口给对象排序,并且在排序时会按照优先级处理其中的元素。
优先队列的头是基于自然排序或者Comparator排序的最小元素。如果有多个对象拥有同样的排序,那么就可能随机地取其中任意一个。当我们获取队列时,返回队列的头对象。
优先队列的大小是不受限制的,但在创建时可以指定初始大小。当我们向优先队列增加元素的时候,队列大小会自动增加。
PriorityQueue是非线程安全的,所以Java提供了PriorityBlockingQueue(实现BlockingQueue接口)用于Java多线程环境。
二、PriorityQueue源码分析
成员:

priavte transient Object[] queue;
private int size = 0;

1.PriorityQueue构造小顶堆的过程
这里我们以priorityQueue构造器传入一个容器为参数PriorityQueue(Collecntion


private void initElementsFromCollection(Collection<? extends E> c) {
  Object[] a = c.toArray();
  // If c.toArray incorrectly doesn't return Object[], copy it.
  if (a.getClass() != Object[].class)
    a = Arrays.copyOf(a, a.length, Object[].class);
  int len = a.length;
  if (len == 1 || this.comparator != null)
    for (int i = 0; i < len; i++)
      if (a[i] == null)
        throw new NullPointerException();
  this.queue = a;
  this.size = a.length;
}

调整,使数据满足小顶堆的结构。
首先介绍两个调整方式siftUp和siftDown
siftDown: 在给定初始化元素的时候,要调整元素,使其满足最小堆的结构性质。因此不停地从上到下将元素x的键值与孩子比较并做交换,直到找到元素x的键值小于等于孩子的键值(即保证它比其左右结点值小),或者是下降到叶子节点为止。
例如如下的示意图,调整9这个节点:
这里写图片描述

private void siftDownComparable(int k, E x) {
  Comparable<? super E> key = (Comparable<? super E>)x;
  int half = size >>> 1;    // size/2是第一个叶子结点的下标
  //只要没到叶子节点
  while (k < half) {
    int child = (k << 1) + 1; // 左孩子
    Object c = queue[child];
    int right = child + 1;
    //找出左右孩子中小的那个
    if (right < size &&
      ((Comparable<? super E>) c).compareTo((E) queue[right]) > 0)
      c = queue[child = right];
    if (key.compareTo((E) c) <= 0)
      break;
    queue[k] = c;
    k = child;
  }
  queue[k] = key;
}

siftUp: priorityQueue每次新增加一个元素的时候是将新元素插入对尾的。因此,应该与siftDown有同样的调整过程,只不过是从下(叶子)往上调整。
例如如下的示意图,填加key为3的节点:
这里写图片描述

private void siftUpComparable(int k, E x) {
  Comparable<? super E> key = (Comparable<? super E>) x;
  while (k > 0) {
    int parent = (k - 1) >>> 1;   //获取parent下标
    Object e = queue[parent];
    if (key.compareTo((E) e) >= 0)
      break;
    queue[k] = e;
    k = parent;
  }
  queue[k] = key;
}

总体的建立小顶堆的过程就是:

private void initFromCollection(Collection<? extends E> c) {
    initElementsFromCollection(c);
    heapify();
  }

其中heapify就是siftDown的过程。
2.PriorityQueue容量扩容过程
从实例成员可以看出,PriorityQueue维护了一个Object[], 因此它的扩容方式跟顺序表ArrayList相差不多。
这里只给出grow方法的源码

private void grow(int minCapacity) {
    int oldCapacity = queue.length;
    // Double size if small; else grow by 50%
    int newCapacity = oldCapacity + ((oldCapacity < 64) ?
                     (oldCapacity + 2) :
                     (oldCapacity >> 1));
    // overflow-conscious code
    if (newCapacity - MAX_ARRAY_SIZE > 0)
      newCapacity = hugeCapacity(minCapacity);
    queue = Arrays.copyOf(queue, newCapacity);
  }

可以看出,当数组的Capacity不大的时候,每次扩容也不大。当数组容量大于64的时候,每次扩容double。
三、PriorityQueue的应用

import java.util.Comparator;
import java.util.PriorityQueue;
import java.util.Queue;

public class test {
    private String name;
    private int population;
    public test(String name, int population)
    {
        this.name = name;
        this.population = population;
    }
    public String getName()
    {
         return this.name;
    }

    public int getPopulation()
    {
         return this.population;
    }
    public String toString()
    {
         return getName() + " - " + getPopulation();
    }
    public static void main(String args[])
    {
        Comparator<test> OrderIsdn =  new Comparator<test>(){
            public int compare(test o1, test o2) {
                // TODO Auto-generated method stub
                int numbera = o1.getPopulation();
                int numberb = o2.getPopulation();
                if(numberb > numbera)
                {
                    return 1;
                }
                else if(numberb<numbera)
                {
                    return -1;
                }
                else
                {
                    return 0;
                }

            }



        };
        Queue<test> priorityQueue =  new PriorityQueue<test>(11,OrderIsdn);



        test t1 = new test("t1",1);
        test t3 = new test("t3",3);
        test t2 = new test("t2",2);
        test t4 = new test("t4",0);
        priorityQueue.add(t1);
        priorityQueue.add(t3);
        priorityQueue.add(t2);
        priorityQueue.add(t4);
        System.out.println(priorityQueue.poll().toString());
    }
}

文章来自脚本之家、优快云

FPGA实现高效数字下变频:CORDIC与CIC滤波器的Verilog优化设计 本文深入探讨了FPGA实现高效数字下变频的技术方案,重点介绍了CORDIC算法与CIC滤波器的Verilog优化设计。通过详细的算法原理分析、FPGA实现技巧和实战经验分享,展示了如何利用CORDIC的旋转运算替代乘法操作,以及CIC滤波器在降采样中的高效性能。文章还提供了完整的系统集成方案和资源优化策略,为无线通信和雷达信号处理领域的工程师提供了实用参考。 阅读详情

相关推荐

载波同步技术(一):BPSK的Costas Loop 载波同步

Author:McCrocodile 2010/11/04          载波的提取在相干解调中往往比较重要,根据信号中是否包含载频分量,载波同步一般也可以分为两种方法。包含载频分量的可以采用窄带滤波或者基本的锁相环环路来实现,不包含的则比较麻烦需要采用特殊的环路实现载波的同步。这里介绍的BPSK的载波恢复就属于后面一种。 对于不包含载频分量的信号载波同步一般有:同相-正交环(就是常说的Costas环)、判决反馈环(几乎可以适用所有调制方式)、同相-正交环衍生环(QPSK松尾环、N相同相-正交环)。

McCrocodile Blog 1万+

java集合--PriorityQueue

PriorityQueue: 1,成员属性 public class PriorityQueue&lt;E&gt; extends AbstractQueue&lt;E&gt; implements java.io.Serializable { private static final long serialVersionUID = -7720805057305804111...

you_never_alone的博客 288

从SPI到JTAG:玩转FT2232H的MPSSE多协议切换指南(附配置代码)

本文详细介绍了如何利用FT2232H芯片的MPSSE技术实现SPI与JTAG协议的无缝切换,提供配置代码和调试技巧。通过解析MPSSE引擎架构和硬件特性,帮助开发者灵活应对多种串行协议需求,提升嵌入式开发效率。特别适合FPGA调试和物联网设备开发场景。

sun99的博客 255

Java 优先级队列(PriorityQueue)

优先级队列是一种有序队列,区别于普通队列 “先进先出(FIFO)” 的规则,它的出队顺序由元素的优先级每次调用poll()(出队)或peek()(查看队首)时,返回的是队列中优先级最高(或最低)的元素;元素的优先级可通过自然排序(实现Comparable接口)或自定义比较器(Comparator)指定;Java 中PriorityQueue是无界队列(默认初始容量 11,可自动扩容),线程不安全;并发场景下需用PriorityBlockingQueue(阻塞优先级队列)。

mikasa667的博客 498

OpenIddict实战:5步搞定.NET Core应用的OIDC单点登录集成

本文详细介绍了如何使用OpenIddict在.NET Core应用中快速实现OIDC单点登录集成。通过五个关键步骤,包括环境准备、数据库集成、客户端注册、令牌配置和多应用SSO集成,帮助开发者高效构建安全的企业级单点登录解决方案。

lambda的博客 728

Android 13 GMS认证避坑:手把手教你搞定RKP配置,解决GTS测试fail

本文详细解析Android 13 GMS认证中的RKP(远程密钥配置)全流程,提供GTS测试失败的深度解决方案。从RKP核心概念到实战配置技巧,帮助开发者规避常见陷阱,确保设备顺利通过Google安全认证,特别适合需要快速掌握Android13 GMS认证的工程师参考。

weixin_29796279的博客 464

最大堆/最小堆、siftup和siftdown

从数据的存储结构看,最大堆/最小堆是一个数组。 从数据的逻辑结构看,最大堆/最小堆是一棵完全二叉树。 堆有以下三种基本操作: 1.初始化:将一个无序的序列初始化成堆。从最后一个非叶子结点开始,自右向左,自下向上,对每一个根结点执行siftdown操作。O(N)。 2.插入。在数组的末尾插入新的元素,然后执行siftup操作。O(logN)。 3.删除。删除指定位置的元素,用数组末

null 1万+

Halcon频域滤波实战:5分钟搞定傅里叶变换与功率谱分析(附完整代码)

本文提供Halcon频域滤波的实战指南,重点讲解如何利用傅里叶变换与功率谱分析快速解决图像处理难题。通过核心算子fft_image和power_real,演示了从空间域转换到频域、分析功率谱以定位周期性噪声,并构造滤波器进行精准去除的完整流程,附有可直接运行的代码示例。

docker8compose的博客 216

算法 之 堆 - Sift-up和Sift-down

1. Sift-up 假定对于某个i&gt;1,H[i]变成了键值大于它父节点键值的元素,这样就违反了堆的特性。我们需要使用Sift-up运算把新的数据项移到在二叉树中适合它的位置上。 Sift-up的运算沿着从H[i]到根节点的唯一一条路径,把H[i]移到适合它的位置上。在沿着路径的每一步上,都将H[i]键值和它父节点的键值H[⌊i/2⌋]相比较。   过程  Sift-up 输入  ...

我不是标题党 1917

SAP S/4HANA 物料分类账(ML)/实际成本核算(Actual Costing)——底表全景 & CKMLCP 执行后数据变化

插入 ML 重估凭证行项目:Dr/Cr 库存科目(期末库存调整)、Dr/Cr COGS/消耗科目(消耗重估)、Cr/Dr ML 重估抵消科目(PRY/PRV 类逻辑)also STPRS/VERPR/PEINH/LBKUM 等(但 S/4 很多“真理”在 ACDOCA)MLPP / MLPPF / MLCR / MLCRF / MLCD / CKMLMV003/004 等。Material Ledger Document(行项目明细:收货/发票价差/结算写入/重估相关)间接(PUP在CKMLCR;

weixin_52203666的博客 587

逆变器技术解析:DDSRF双解耦在正负序分离中的关键作用

本文深入解析了DDSRF双解耦技术在逆变器正负序分离中的关键作用。通过建立正反旋转坐标系并利用交叉反馈解耦网络,DDSRF能快速、精准地分离电网电压中的正负序分量,从而显著提升锁相环在电网不平衡条件下的精度与系统稳定性,是现代高性能并网逆变器的核心算法之一。

m3n5b7v8c9x的博客 412

java固定队列_Java 使用最大堆实现优先级队列。堆大小固定,并使用数组表示。...

import java.util.Arrays;/** from 时 代 J a v a 公 众 号 - nowjava.com**/public class PriorityQueue {int[] heap;int size;// Constructor initializes instance variablespublic PriorityQueue(int maxSiz...

weixin_39669769的博客 307

企业微信第三方应用014_企业微信5种第三方应用的安装方式_上架到应用市场_服务商后台点击安装测试_生成应用推广二维码安装---企业微信开发016

成员授权的意思就是,只要是这个成员扫码安装了这个应用,那么这个应用就只有这个成员可以用。安装的时候可以设置可见范围,这个地方可以设置整个公司或者是某个部门或者是某些人可以让这个应用来进行操作。创建了以后,这个二维码就可以发出来进行推广别人用户扫描了以后就可以把自己的企业微信给安装上对应的应用了。然后在对应的这个微信的企业后台就可以看到在第三方中有这个应用了。可以看到这个就是服务商的后台对应的一个应用,我们点击打开应用。可以看到这里有两个授权,一个是成员授权,一个是管理员授权。就可以去创建推广二维码了。

添柴程序猿的专栏 592

[PriorityQueue]:Java中PriorityQueue的用法

Class PriorityQueue java.util.PriorityQueue 不指定Comparator时默认为最小堆,通过传入自定义的Comparator函数可以实现大顶堆。 PriorityQueue<Integer> minHeap = new PriorityQueue<Integer>(); //小顶堆,默认容量为11 PriorityQueue&lt...

shinezzz的博客 9673

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

Java优先队列(PriorityQueue)

参考 http://www.importnew.com/6932.html https://www.cnblogs.com/gnivor/p/4841191.html 我们知道队列是遵循先进先出(First-In-First-Out)模式的,但有些时候需要在队列中基于优先级处理对象。举个例子,比方说我们有一个每日交易时段生成股票报告的应用程序,需要处理大量数据并且花费很多处理时间。客户向这个应用程......

try to do 3万+

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

Java之PriorityQueue的用法

方法作用add();队尾插入元素,调整堆结构,失败时抛异常offer();队尾插入元素,调整堆结构,失败时抛falseremove();根据value值删除指定元素,调整堆结构,失败时抛异常poll();删除队头元素,调整堆结构,失败时抛nullelement();获取队列头元素peek();获取队列头元素clear();清空队列size();获取队列元素个数contains();判断队列中是否包含指定元素isEmpty();判断队列是否为空。

个人学习所用博客,记录日常学习的过程。 6938

Java PriorityQueue(优先队列)

Java PriorityQueue类是一种队列数据结构实现,其中根据优先级处理对象。它与遵循FIFO(先进先出)算法的标准队列不同。 在优先级队列中,添加的对象根据其优先级。默认情况下,优先级由对象的自然顺序决定。队列构建时提供的比较器可以覆盖默认优先级。 优先级队列 1. PriorityQueue功能 让我们记下PriorityQueue上的几个要点。 PriorityQueu...

javaZhong的博客 6万+

java中priorityqueue_JAVA中priorityqueue详解

Java中PriorityQueue通过二叉小顶堆实现,可以用一棵完全二叉树表示。本文从Queue接口函数出发,结合生动的图解,深入浅出地分析PriorityQueue每个操作的具体过程和时间复杂度,将让读者建立对PriorityQueue建立清晰而深入的认识。 总体介绍前面以JavaArrayDeque_为例讲解了_Stack_和_Queue,其实还有一种特殊的队列叫做_PriorityQue...

weixin_35794740的博客 176

java中priorityqueue_详解JAVA中priorityqueue的具体使用

Java中PriorityQueue通过二叉小顶堆实现,可以用一棵完全二叉树表示。本文从Queue接口函数出发,结合生动的图解,深入浅出地分析PriorityQueue每个操作的具体过程和时间复杂度,将让读者建立对PriorityQueue建立清晰而深入的认识。总体介绍前面以JavaArrayDeque为例讲解了Stack和Queue,其实还有一种特殊的队列叫做PriorityQueue,即优先队...

weixin_39564527的博客 1389

Java集合 - PriorityQueue

Java集合 - PriorityQueue

qq_43350524的博客 1059

Java中的PriorityQueue,Java中PriorityQueue

刷题的时候遇到了一个题要用到PriorityQueue,所以查查资料,以后备用。定义:publicclassPriorityQueueextendsAbstractQueueimplementsSerializable不同于传统的Queue,PriorityQueue并不是通常情况下,默认的FIFO,而是自定义一种优先级的方式,每次输出是最高优先级的数据,而不是第一次进入的数据。比如优先级...

weixin_28867883的博客 238

Java中PriorityQueue的排序

PrioriryQueue是Queue接口的一个队列实现类,但它的排序并不是典型的队列式先进先出(FIFO)的方式。 PriorityQueue的排序方式分为两种,一种是自然排序,这是按照加入元素的大小从小到大排序的。第二种是定制排序,是使用comparator类来重写compare(Object o1,Object o2)方法来实现定制排序的。但是这些都不是关键,关键在于PriorityQ

淡然坊 7828

JAVA中PRIORITYQUEUE详解

前面以JavaArrayDeque为例讲解了Stack和Queue,其实还有一种特殊的队列叫做,即优先队列。优先队列的作用是能保证每次取出的元素都是队列中权值最小的(Java的优先队列每次取最小元素,C++的优先队列每次取最大元素)。这里牵涉到了大小关系,元素大小的评判可以通过元素本身的自然顺序(),也可以通过构造时传入的比较器(Comparator,类似于C++的仿函数)。Java中实现了Queue接口,不允许放入null元素;其通过堆实现,具体说是通过完全二叉树()实现的。

guanshengg的博客 369

对JAVA的PriorityQueue的深入理解

发现它是一个接口,更具提供的方法的方法名我们可以知道这是一个定义对象的比较顺序的一个接口这个接口我们今天先不仔细展开,只需知道里面最重要的方法是compare()用来定义两个对象的比较关系。这两个方法几乎相同,唯一的差别就是比较对象顺序使用的方法不同,一个是使用你传入的comparator对象定义的方法来比较对象顺序,一个是使用对象是实现了Compara接口里的comparaTo方法来比较,这两个方法功能是一样的,就是使得我们传入的集合对象变成一个堆。但我们还是继续看完堆剩下的两个构造方法,

weixin_61854715的博客 1052

[java队列]——PriorityQueue

[java队列]——PriorityQueuePriorityQueue介绍PriorityQueue内部实现基本属性构造方法入队扩容出队取队头元素,并不出队PriorityQueue总结Queue接口 PriorityQueue介绍 上一篇[java队列]——ArrayBlockingQueue介绍了数组方式实现的阻塞队列。这篇将介绍PriorityQueue优先级队列。其简介如下: 优先级队...

way2016的博客 491

JAVA中的PriorityQueue

Java中PriorityQueue通过二叉小顶堆实现,可以用一棵完全二叉树表示。本文从Queue接口函数出发,结合生动的图解,深入浅出地分析PriorityQueue每个操作的具体过程和时间复杂度,将让读者建立对PriorityQueue建立清晰而深入的认识。 总体介绍 前面以Java ArrayDeque为例讲解了Stack和Queue,其实还有一种特殊的队列叫做PriorityQueue,即...

qq_43170213的博客 1万+

java中priorityQueue详解

以前转自https://www.cnblogs.com/Elliott-Su-Faith-change-our-life/p/7472265.html,现已404,学习使用保存转载,有疑问联系删除,谢谢! Java中PriorityQueue通过二叉小顶堆实现,可以用一棵完全二叉树表示。本文从Queue接口函数出发,结合生动的图解,深入浅出地分析PriorityQueue每个操作的具体过程和时间复杂度,将让读者建立对PriorityQueue建立清晰而深入的认识。 总体介绍 前面以JavaArra..

独行侠的守望の博客 2103
上一篇: 递归--全排列
下一篇: 51nod--1117-聪明的木匠
jeffery0628
博客等级 码龄11年 39粉丝 112原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值