PriorityQueue介绍

    • 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;}@Overridepublic 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方法逻辑:

  @Overridepublic 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> {@Overridepublic 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>() {@Overridepublic 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>() {@Overridepublic 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]    18int val = minHeap.peek();  //27if(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.rhkb.cn/news/118395.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Windows7安装SSH客户端的解决方案

大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。现为CSDN博客专家、人工智能领域优质创作者。喜欢通过博客创作的方式对所学的…

C语言深入理解指针(非常详细)(二)

目录 指针运算指针-整数指针-指针指针的关系运算 野指针野指针成因指针未初始化指针越界访问指针指向的空间释放 如何规避野指针指针初始化注意指针越界指针不使用时就用NULL避免返回局部变量的地址 assert断言指针的使用和传址调用传址调用例子&#xff08;strlen函数的实现&a…

开开心心带你学习MySQL数据库之第三篇上

学校的项目组有必要加入吗? 看你的初心. ~~如果初心是通过这个经历能够提高自己的技术水平 ~~是可以考虑的 ~~如果初心是通过这个经历提高自己找工作的概率 ~~这个是不靠谱的,啥用没有 ~~如果初心是通过这个体验更美好的大学生活 ~~靠谱的 秋招,应届生,找工作是非常容易的!!! …

JavaScript -【第二周】

文章来源于网上收集和自己原创&#xff0c;若侵害到您的权利&#xff0c;请您及时联系并删除~~~ 理解什么是流程控制&#xff0c;知道条件控制的种类并掌握其对应的语法规则&#xff0c;具备利用循环编写简易ATM取款机程序能力 运算符语句综合案例 1. 运算符 算术运算符赋值运…

无涯教程-Android - AutoCompleteTextView函数

AutoCompleteTextView是一个类似于EditText的视图&#xff0c;只是它在用户键入时自动显示补充数据。 AutoCompleteTextView - 属性 以下是与AutoCompleteTextView控件相关的重要属性。您可以查看Android官方文档以获取属性的完整列表以及可以在运行时更改这些属性的相关方法。…

2023新版医保目录明细(药品查询)

查询医保目录的主要目的是为了了解医保政策对于特定医疗服务、药品和医疗器械的覆盖范围和支付标准。大众可以通过查看医保目录可以确定哪些药品可以被医保支付以及报销的比例和限额&#xff1b;医药从业者可通过查看医保目录可以即使了解医保政策的变化&#xff0c;便于做出相…

【附安装包】CAD2024(建筑版)安装教程

软件下载 软件&#xff1a;CAD建筑版本&#xff1a;2023语言&#xff1a;简体中文大小&#xff1a;4.52G安装环境&#xff1a;Win11/Win10硬件要求&#xff1a;CPU2.5GHz 内存8G(或更高&#xff09;下载通道①百度网盘丨64位下载链接&#xff1a;https://pan.baidu.com/s/1cHe…

RT-Thread 中断管理学习(一)

中断管理 什么是中断&#xff1f;简单的解释就是系统正在处理某一个正常事件&#xff0c;忽然被另一个需要马上处理的紧急事件打断&#xff0c;系统转而处理这个紧急事件&#xff0c;待处理完毕&#xff0c;再恢复运行刚才被打断的事件。生活中&#xff0c;我们经常会遇到这样…

CS420 课程笔记 P2 - 内存编辑和基础的 GameHacking 尝试

文章目录 IntroductionOperating SystemToolsMemory ScanningMemory ScanExamples!Conclusion Introduction 本节将介绍操作系统的基础知识和内存扫描&#xff0c;这可以说是 game hacking 中最重要的技能&#xff0c;我们不会深入讨论操作系统&#xff0c;因为这本身就是一门…

988. 从叶结点开始的最小字符串

988. 从叶结点开始的最小字符串 C代码&#xff1a;DFS /*** Definition for a binary tree node.* struct TreeNode {* int val;* struct TreeNode *left;* struct TreeNode *right;* };*/// 叶子节点// 每一层用一个pathTop、遇到叶子节点就判断一次&#xff1b;…

Flutter 项目结构文件

1、Flutter项目的文件结构 先helloworld项目&#xff0c;看看它都包含哪些组成部分。首先&#xff0c;来看一下项目的文件结构&#xff0c;如下图所示。 2、介绍上图的内容。 -litb/main.dart文件&#xff1a;整个应用的入口文件&#xff0c;其中的main函数是整个Flutter应…

MATLAB中isequal函数转化为C语言

背景 有项目算法使用matlab中isequal函数进行运算&#xff0c;这里需要将转化为C语言&#xff0c;从而模拟算法运行&#xff0c;将算法移植到qt。 MATLAB中isequal简单介绍 语法 tf isequal(A,B) tf isequal(A1,A2,...,An) 说明 如果 A 和 B 等效&#xff0c;则 tf is…

DHorse v1.3.2 发布,基于 k8s 的发布平台

版本说明 新增特性 构建版本、部署应用时的线程池可配置化&#xff1b; 优化特性 构建版本跳过单元测试&#xff1b; 解决问题 解决Vue应用详情页面报错的问题&#xff1b;解决Linux环境下脚本运行失败的问题&#xff1b;解决下载Maven安装文件失败的问题&#xff1b; 升…

分布式集群框架——有关zookeeper的面试考点

3.掌握Zookeeper的概念 当涉及到大规模分布式系统的协调和管理时&#xff0c;Zookeeper是一个非常重要的工具。 1. 分布式协调服务&#xff1a;Zookeeper是一个分布式协调服务&#xff0c;它提供了一个高可用和高性能的环境&#xff0c;用于协调和同步分布式系统中的各个节点…

操作系统中一些零散的知识点

第三章 内存管理 在虚拟内存系统中&#xff0c;虚拟内存的最大容量是由计算机的地址结构&#xff08;CPU寻址范围&#xff09;确定的&#xff0c;而虚拟内存的实际容量是受到“内存大小磁盘空间大小”、“地址线位数”共同制约&#xff0c;取二者最小值实现虚拟内存管理必须有…

【Apollo学习笔记】——规划模块TASK之RULE_BASED_STOP_DECIDER

文章目录 前言RULE_BASED_STOP_DECIDER相关配置RULE_BASED_STOP_DECIDER总体流程StopOnSidePassCheckClearDoneCheckSidePassStopIsPerceptionBlockedIsClearToChangeLaneCheckSidePassStopBuildStopDecisionELSE:涉及到的一些其他函数NormalizeAngleSelfRotate CheckLaneChang…

【包过滤防火墙——firewalld动态防火墙】的简单使用

文章目录 firewald与iptables区别firewalld九个区域firewalld配置方法firewalld参数和命令firewalld两种模式firewalld使用实验 firewalld不要与iptables混用 firewald与iptables区别 iptables 主要是基于接口&#xff0c;来设置规则&#xff0c;从而判断网络的安全性。firewa…

UE4 春节鞭炮

先搞个基类&#xff0c;一个鞭炮的 搞个鞭炮类&#xff0c;存多个鞭炮 在构造函数的位置先生成对应的鞭炮数 将鞭炮绑定到绳子上&#xff0c;随绳子摆动而一起摆动 在基类里面写爆炸事件 最后用Timer去调用

docker-compose 部署 Seata整合nacos,Postgresql 为DB存储

docker-compose 部署 Seata整合nacos,Postgresql 为DB存储 环境 详情环境可参考 https://github.com/alibaba/spring-cloud-alibaba/wiki/%E7%89%88%E6%9C%AC%E8%AF%B4%E6%98%8E 我这里 <spring.cloud.alibaba-version>2021.1</spring.cloud.alibaba-version>所…

linux的make和makefile学习

linux的make和makefile学习 准备工作使用GNU链接库链接到math库编写复利程序 创建自己的库链接到主目录 不同的C标准系统调用write()获取头文件信息功能测试宏 准备工作 安装GCC和Make工具 安装中文输入法 参考&#xff1a;http://t.csdn.cn/eH0Ow sudo apt-get update sudo…