PriorityQueue介绍

news2025/1/19 16:34:59

    • PriorityQueue
    • 堆的应用
      • 找前k个最小数据(TOPK问题)
      • 求k个最小的数优化
      • 堆排序

PriorityQueue

Java集合框架中提供了PriorityQueue和PriorityBlockingQueue(优先级阻塞队列)两种类型的优先级队列,PriorityQueue是线程不安全的,PriorityBlockingQueue是线程安全的。
在这里插入图片描述

在这里插入图片描述

常用方法:
在这里插入图片描述
1:当你没传入比较器时候;PriorityQueue中放置的元素必须要能够比较大小,不能插入无法比较大小的对象,否则会抛出ClassCastException异常(如果放自定义类型;可以通过实现compareable接口;重写compareTo方法;传比较器优先级比较高)

class Student implements Comparable<Student>{
    public int age;
    public Student(int age) {
        this.age = age;
    }

    @Override
    public int compareTo(Student o) {
        //return this.age - o.age;
        return this.age - o.age;
    }
}

2:不能插入null对象,否则会抛出NullPointerException
3:入和删除元素的时间复杂度为log(N)
4:PriorityQueue默认情况下是小堆—即每次获取到的元素都是最小的元素
5:使用时必须导入PriorityQueue所在的包,即:importjava.util.PriorityQueue;

默认是小堆;如果想要大堆;如何变成大堆?
重写compareTo方法逻辑:

  @Override
    public int compareTo(Student o) {
        //return this.age - o.age;
        return o.age - this.age;
    }

PriorityQueue还有其它构造方法;比如传比较器的构造方法:PriorityQueue queue = new PriorityQueue<>(Comparator<? super E> comparator);
这个构造方法创建一个空的优先级队列,并使用指定的比较器来确定元素的排序顺序。(这个使用比较器的指定顺序是比较优先的;还有一个构造方法是通过集合类和比较器构建优先级队列;那么不会用默认的比较方法;而是比较器的)

class IntCmp implements Comparator<Integer> {

    @Override
    public int compare(Integer o1, Integer o2) {
        //return o2-o1;
        return o2.compareTo(o1);
    }
}

PriorityQueue priorityQueue = new PriorityQueue<>(new IntCmp());

扩容机制:满了它会自动扩容的
如果容量小于64时,是按照oldCapacity的2倍方式扩容的
如果容量大于等于64,是按照oldCapacity的1.5倍方式扩容的
如果容量超过MAX ARRAY SIZE(MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8),按照MAX ARRAY_SIZE来进行扩容。
在 Java 中,数组是由连续的内存空间组成的数据结构,而每个对象都会占用一定的内存空间。因此,在数组中存储对象时,需要考虑额外的内存开销。
在 PriorityQueue 中,减去 8 的目的是为了留出足够的空间,以容纳对象引用和一些额外的内部数据,如对象头信息等。这些额外的开销包括。

匿名内部类写这个代码:

 PriorityQueue<Student> priorityQueue = new PriorityQueue<>(2, new Comparator<Student>() {
            @Override
            public int compare(Student o1, Student o2) {
                return o2.age - o1.age;
            }
        });

堆的应用

找前k个最小数据(TOPK问题)

最大或者最小的前k个数据。有10W个数据,让你找到前K个最大/最小的数据。
粗暴法:

  //   最大或者最小的前k个数据。有10W个数据,让你找到前K个最大/最小的数据。
    public int[] smallstk(int []arr,int k){
        Arrays.sort(arr);
        int[] tmp=new int[k];
        for (int i = 0; i <k ; i++) {
            System.out.println(arr[i]);
            tmp[i]=arr[i];
        }
        return tmp;
    }

提问:Arrays.sort(arr);底层是什么呢?
TimSort”的混合排序算法。TimSort 是结合了归并排序和插入排序的排序算法:
TimSort 的底层细节包括以下关键步骤:
1:数据分块;输入数组被分成多个小块(或称为"run"),每个小块都是已经排好序的。
2:合并排序;TimSort 使用归并排序来合并这些小块,将它们逐步合并成较大的块,直到得到一个完全有序的数组。
3:插入排序;在合并过程中,TimSort 使用插入排序来进一步优化性能,确保排序操作尽可能高效。

小堆实现:存进堆里;然后再取出来

    //使用小堆实现
    public int [] smallstk1(int []arr,int k){
        PriorityQueue<Integer> priorityQueue=new PriorityQueue<>();
        for (int i = 0; i <arr.length ; i++) {
            priorityQueue.offer(arr[i]);
        }
        int []tmp=new int[k];
        for (int i = 0; i < k; i++) {
            tmp[i]=priorityQueue.poll();
            
        }
        return tmp; 
    }

时间复杂度nlogn,第一个循环复杂度O(n)第二个循环的复杂度你nlogn;复杂度这方面确实不是很行。能否优化一下呢?

求k个最小的数优化

逻辑:1:先将最先k个元素建立大堆
2:从k后面开始就每一次往后走比较堆顶元素和数组元素大小,如果堆顶比较小就没什么事直接数组往后走。
如果堆顶比较大,就把堆顶弹出(它会自动调整为大堆),并且把这个数组元素加入进去(让它自动调整为大堆)再往后走

    public static int[] smallestK3(int[] arr, int k) {
        //不加这句会报异常,源码
        if(arr == null || k == 0) {
            return new int[0];
        }
        //1. 建立一个大根堆
        PriorityQueue<Integer> minHeap = new PriorityQueue<>(k, new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return o2.compareTo(o1);
            }
        });

        //2、
        for (int i = 0; i < arr.length; i++) {
            if(minHeap.size() < k) {
                minHeap.offer(arr[i]);
            }else {
                //当前数组的元素是arr[i]    18
                int val = minHeap.peek();  //27
                if(val > arr[i]) {
                    //弹出大的
                    minHeap.poll();
                    //放进小的
                    minHeap.offer(arr[i]);
                }
            }
        }

        //3 最把这个堆的全部元素弹给数组记录下来
        int[] tmp = new int[k];
        for (int i = 0; i < k; i++) {
            tmp[i] = minHeap.poll();
        }
        return tmp;
    }

堆排序

如果要排序一组数,从小到大(让下标有序):
使用小堆:这是不可能实现的;每次弹出最小的没有问题;但是放到哪去;如果放别的地方;空间复杂度就变大了;但是小堆,你也不一定就有序,左右谁大谁小不知道。
使用大堆:每次堆顶和最后一个交换。然后它再自动的排序好大堆。然后我们就不能包含这个最后的元素。交换位置由最后一个元素往前走一步(反之排序建立小堆)我都不用弹出处理交换,直接在原来数组交换。换完排序就好了。所以这才叫堆排序。
代码:

    //堆排序
    public void heapSort(int []array){
        int usedSize=array.length;//usedSize是有效元素个数
        int end=usedSize-1;
        while (end>0){
            //交换0位置和最后的位置;最后的位置放最大值;每次往前走
            int tmp=elem[0];
            elem[0]=elem[end];
            elem[end]=tmp;
            
            shiftDown(0,end);
            end--;//end传的是数组元素下标,10个元素,我减1。,是不是只调整9个元素。每次结束就少一个元素调整(end--)
        }

    }

时间复杂度:建立堆的复杂度O(n)
O(n) +O(nlogn)约等于O(nlogn)
空间复杂度O(1);没有浪费,创建额外的空间

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/967086.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

IIS CGI配置和CGI程序FreeBasic, VB6, VC 简单样例

如果说COM和DLL让程序间交互数据变得方便&#xff0c;那CGI这门简单而又古老的技术让网络上数据交互变得方便。虽然古老&#xff0c;但浩瀚的互联网上和世界各地的企业内部&#xff0c;仍有许许多多并发访问量不大的业务在使用这门技术。今天做个回顾&#xff0c;并列出一些例子…

完全平方数

题目链接 完全平方数 题目描述 注意点 返回 和为 n 的完全平方数的最少数量 解答思路 初始想到使用动态规划&#xff0c;后续数字的完全平方数可以由前面数字的完全平方数求得&#xff0c;对于任意数字&#xff0c;可以计算其减去从1…i之间&#xff08;保证做减操作后的值…

Unity中Shader的面剔除Cull

文章目录 前言一、Unity中Shader的面是否剔除&#xff0c;是由我们自己决定的二、暴露一个属性来控制 剔除模式三、如何区分正反面 前言 Unity中Shader的面剔除 Cull Off | Back | Front 一、Unity中Shader的面是否剔除&#xff0c;是由我们自己决定的 使用 Cull Off | Back |…

深度学习之视频分类项目小记

写在前面&#xff0c;最近一阵在做视频分类相关的工作&#xff0c;趁有时间来记录一下。本文更注重项目实战与落地&#xff0c;而非重点探讨多模/视频模型结构的魔改 零、背景 目标&#xff1a;通过多模态内容理解技术&#xff0c;构建视频层级分类体系原技术方案&#xff1a…

Pyecharts数据可视化(二)

目录 1.绘制散点图 2.绘制饼图 2.1绘制实心饼图 2.2 绘制圆形饼图 2.3 绘制玫瑰图 3.绘制漏斗图 4.绘制仪表盘 5.绘制组合图表 本文主要介绍如何利用Pyecharts来绘制一些常用的可视化图形&#xff0c;比如散点图、饼图、漏斗图等等&#xff0c;具体的绘制方法请见下文。 …

通讯软件014——分分钟学会Matrikon HDA Explorer

本文介绍如何使用Matrikon HDA Explorer工具软件进行OPC HDA通讯调试。相关软件可登录网信智汇&#xff08;wangxinzhihui.com&#xff09;下载。 1、连接OPC HDA Server数据源“Kepware.KEPServerEX HAD.V6”。 2、添加标签&#xff1a;右键点击“Kepware.KEPServerEX HAD.V6”…

[管理与领导-66]:IT基层管理者 - 辅助技能 - 4- 职业发展规划 - 乌卡时代(VUCA )的团队管理思维方式的转变

目录 一、乌卡时代人与公司的关系的转变 二、乌卡时代管理方式的转变 三、乌卡时代的管理与传统时代的管理比较 四、乌卡时代管理者的挑战 五、乌卡时代如何做好管理 六、个人能力要求 一、乌卡时代人与公司的关系的转变 在乌卡时代&#xff08;指虚拟办公、远程工作等数…

3分钟:腾讯云免费SSL证书申请教程_免费HTTPS证书50张

2023腾讯云免费SSL证书申请流程&#xff0c;一个腾讯云账号可以申请50张免费SSL证书&#xff0c;免费SSL证书为DV证书&#xff0c;仅支持单一域名&#xff0c;申请腾讯云免费SSL证书3分钟即可申请成功&#xff0c;免费SSL证书品牌为TrustAsia亚洲诚信&#xff0c;腾讯云百科分享…

一些测试知识

博客主页&#xff1a; https://blog.csdn.net/qq_57785602/category_12023254.html?spm1001.2014.3001.5482https://blog.csdn.net/qq_57785602/category_12023254.html?spm1001.2014.3001.5482 图片网上找的&#xff0c;文章看书或者是平常逛博客看到的&#xff0c;如有侵…

本地部署 Llama2-Code-Interpreter

本地部署 Llama2-Code-Interpreter 1. Llama2-Code-Interpreter 是什么2. Llama2-Code-Interpreter 主要特点3. 部署 Llama2-Code-Interpreter4. 运行 Llama2-Code-Interpreter5. 访问 Llama2-Code-Interpreter 1. Llama2-Code-Interpreter 是什么 该项目允许 LLM 根据整个流程…

设计模式系列-原型模式

一、上篇回顾 上篇创建者模式中&#xff0c;我们主要讲述了创建者的几类实现方案&#xff0c;和创建者模式的应用的场景和特点&#xff0c;创建者模式适合创建复杂的对象&#xff0c;并且这些对象的每 个组成部分的详细创建步骤可以是动态的变化的&#xff0c;但是每个对象的组…

C语言入门 Day_12 一维数组

目录 前言 1.创建一维数组 2.使用一维数组 3.易错点 4.思维导图 前言 存储一个数据的时候我们可以使用变量&#xff0c; 比如这里我们定义一个记录语文考试分数的变量chinese_score&#xff0c;并给它赋值一个浮点数&#xff08;float&#xff09;。 float chinese_scoe…

服务器挂机赚钱之Traffmonetizer教程挂机,利用闲置的Vps赚钱

互联网VPS赚钱的项目traffmonetizer挂机&#xff0c;原理就是traffmonetizer通过共享闲置的带宽售卖给平台&#xff0c;然后平台将产生的收益就归你。如果你有闲置的vps服务器都可以通过traffmonetizer挂机赚钱。 VPS赚钱开始注册 实话实说吧&#xff0c;这个就是来拉人头的&…

使用 Python 和 dash 创建仪表板

推荐&#xff1a;使用 NSDT场景编辑器快速搭建3D应用场景 介绍 在数据科学和分析领域&#xff0c;数据的力量不仅通过提取见解来释放&#xff0c;而且还通过有效地传达这些见解来释放;这就是数据可视化发挥作用的地方。 数据可视化是信息和数据的图形表示。它使用图表、图形和…

CC1310开发工具下载及环境搭建

目录 CC1310开发工具集 CC1310SDK下载安装注意事项 CCS下载安装注意事项 导入示例代码 CCS常用设置 CC1310是TI的一款sub1G射频模块&#xff0c;具体参数见数据手册吧&#xff08;CC1310数据手册、用户手册下载&#xff1a;https://dev.ti.com/tirex/explore/node?nodeA_…

2024年java面试--多线程(2)

系列文章目录 2024年java面试&#xff08;一&#xff09;–spring篇2024年java面试&#xff08;二&#xff09;–spring篇2024年java面试&#xff08;三&#xff09;–spring篇2024年java面试&#xff08;四&#xff09;–spring篇2024年java面试–集合篇2024年java面试–redi…

leetcode 189. 轮转数组

2023.9.3 k的取值范围为0~100000&#xff0c;此时需要考虑到两种情况&#xff0c;当k为0时&#xff0c;此时数组不需要轮转&#xff0c;因此直接return返回&#xff1b;当k大于等于数组nums的大小时&#xff0c;数组将会转为原来的数组&#xff0c;然后再接着轮转&#xff0c;此…

Linux系统下的zabbix监控平台(单机安装服务)

目录 一、zabbix的基本概述 二、zabbix构成 1.server 2.web页面 3.数据库 4.proxy 5.Agent 三、监控对象 四、zabbix的日常术语 1.主机(host) 2.主机组(host group) 3.监控项(item) 4.触发器(trigger) 5.事件&#xff08;event&#xff09; 6.动作&#xff08;a…

docker笔记4:高级复杂安装-mysql主从复制

1.主从搭建步骤 1.1新建主服务器容器实例3307 docker run -p 3307:3306 --name mysql-master \ -v /mydata/mysql-master/log:/var/log/mysql \ -v /mydata/mysql-master/data:/var/lib/mysql \ -v /mydata/mysql-master/conf:/etc/mysql \ -e MYSQL_ROOT_PASSWORDroot \ -d…

java八股文面试[多线程]——虚假唤醒

阻塞队列中&#xff0c;如果需要线程挂起操作&#xff0c;判断有无数据的位置采用的是while循环 &#xff0c;为什么不能换成if 肯定是不能换成if逻辑判断 线程A&#xff0c;线程B&#xff0c;线程E&#xff0c;线程C。 其中ABE生产者&#xff0c;C属于消费者 put阻塞代码&a…