Java->优先级队列(堆)

一、优先级队列

1.概念

数据结构应该提供两个最基本的操作,一个是返回最高优先级对象,一个是添加新的对象。这种数
据结构就是优先级队列(Priority Queue)。

2.堆的概念

把它的所有元素按完全二叉树的顺序存储方式存储 在一个一维数组中

3.堆的性质

堆中某个节点的值总是不大于或不小于其父节点的值;
堆总是一颗完全二叉树

4.堆的存储方式

堆是一棵完全二叉树,因此可以层序的规则采用顺序的方式来高效存储

非完全二叉树,则不适合使用顺序方式进行存储,因为为了能够还原二叉树,空间中必须要存储空节点,就会导致空间利用率比较低

如果i为0,则i表示的节点为根节点,否则i节点的双亲节点为 (i - 1)/2
如果2 * i + 1 小于节点个数,则节点i的左孩子下标为2 * i + 1,否则没有左孩子
如果2 * i + 2 小于节点个数,则节点i的右孩子下标为2 * i + 2,否则没有右孩子
 

5.堆的创建

向下调整:

5.1大根堆
public class TextHeap {public int[] elem;public int useSized;public TextHeap() {this.elem = new int[10];}public void intiElem(int[] array) {for (int i = 0; i < array.length; i++) {this.elem[i] = array[i];useSized++;}}public void creatHeap() {for (int parent = (useSized - 1 - 1) / 2; parent >= 0; parent--) {siftDown(parent, useSized);}}private void siftDown(int parent, int useSized) {int child = parent * 2 + 1;while (child < useSized) {if(child + 1 < useSized && elem[child] < elem[child+1]) child++;if (elem[child] > elem[parent]) {swap(elem, child, parent);parent = child;child = parent * 2 + 1;} else {break;}}}private void swap(int[] elem, int i, int j) {int tmp = elem[i];elem[i] = elem[j];elem[j] = tmp;}
}import java.util.Arrays;public class Text {public static void main(String[] args) {TextHeap textHeap = new TextHeap();int[] arr = new int[]{ 27,15,19,18,28,34,65,49,25,37 };textHeap.intiElem(arr);textHeap.creatHeap();System.out.println(Arrays.toString(textHeap.elem));}
}
//[65, 49, 34, 25, 37, 27, 19, 18, 15, 28]
5.2小根堆
public class TextHeap {public int[] elem;public int useSized;public TextHeap() {this.elem = new int[10];}public void intiElem(int[] array) {for (int i = 0; i < array.length; i++) {this.elem[i] = array[i];useSized++;}}public void creatHeap() {for (int parent = (useSized - 1 - 1) / 2; parent >= 0; parent--) {siftDown(parent, useSized);}}private void siftDown(int parent, int useSized) {int child = parent * 2 + 1;while (child < useSized) {if(child + 1 < useSized && elem[child] > elem[child+1]) child++;if (elem[child] < elem[parent]) {swap(elem, child, parent);parent = child;child = parent * 2 + 1;} else {break;}}}private void swap(int[] elem, int i, int j) {int tmp = elem[i];elem[i] = elem[j];elem[j] = tmp;}
}import java.util.Arrays;public class Text {public static void main(String[] args) {TextHeap textHeap = new TextHeap();int[] arr = new int[]{ 27,15,19,18,28,34,65,49,25,37 };textHeap.intiElem(arr);textHeap.creatHeap();System.out.println(Arrays.toString(textHeap.elem));}
}
//[15, 18, 19, 25, 28, 34, 65, 49, 27, 37]

6.建堆的时间复杂度

//时间复杂度:O(logn)
siftDown() {
}//时间复杂度:O(n)
creatHeap() {
}//n为树的节点数

 

 7.堆的插入

堆的插入总共需要两个步骤:
1. 先将元素放入到底层空间中(注意:空间不够时需要扩容)
2. 将最后新插入的节点向上调整,直到满足堆的性质

    public void offer(int val) {if (isFull()) elem = Arrays.copyOf(elem, elem.length * 2);elem[useSized] = val;siftUp(useSized);useSized++;}private void siftUp(int child) {int parent = (child - 1) / 2;while (parent >= 0) {if (elem[parent] < elem[child]) {swap(elem, parent, child);child = parent;parent = (child - 1) / 2;} else {break;}}}private boolean isFull() {return useSized == elem.length;}private void swap(int[] elem, int i, int j) {int tmp = elem[i];elem[i] = elem[j];elem[j] = tmp;}

 8.堆的删除

注意:堆的删除一定删除的是堆顶元素。具体如下:
1. 将堆顶元素对堆中最后一个元素交换
2. 将堆中有效数据个数减少一个
3. 对堆顶元素进行向下调整

    public void poll() {if (isEmpty()) return;swap(elem, 0, useSized - 1);useSized--;siftDown(0, useSized);}private void siftDown(int parent, int useSized) {int child = parent * 2 + 1;while (child < useSized) {if (child + 1 < useSized && elem[child] < elem[child + 1]) child++;if (elem[child] > elem[parent]) {swap(elem, child, parent);parent = child;child = parent * 2 + 1;} else {break;}}}private void swap(int[] elem, int i, int j) {int tmp = elem[i];elem[i] = elem[j];elem[j] = tmp;}public boolean isEmpty() {return useSized == 0;}

二、PriorityQueue

1.什么是PriorityQueue

Java集合框架中提供了PriorityQueue和PriorityBlockingQueue两种类型的优先级队列,PriorityQueue是线程不安全的,PriorityBlockingQueue是线程安全的

2.PriorityQueue的特性

关于PriorityQueue的使用要注意:
1. 使用时必须导入PriorityQueue所在的包,即:import java.util.PriorityQueue
2. PriorityQueue中放置的元素必须要能够比较大小,不能插入无法比较大小的对象,否则会抛出
ClassCastException异常
3. 不能插入null对象,否则会抛出NullPointerException
4. 没有容量限制,可以插入任意多个元素,其内部可以自动扩容
5. 插入和删除元素的时间复杂度为O(logn)
6. PriorityQueue底层使用了堆数据结构
7. PriorityQueue默认情况下是小堆---即每次获取到的元素都是最小的元素

默认情况下,PriorityQueue队列是小堆,如果需要大堆需要用户提供比较器:

import java.util.Comparator;
import java.util.PriorityQueue;
// 自己定义的比较器:直接实现Comparator接口,然后重写该接口中的compare方法即可
class IntBig implements Comparator<Integer> {@Overridepublic int compare(Integer o1,Integer o2) {return o2.compareTo(o1);
//小根堆
//      return o1.compareTo(o2);}
}public class Text {public static void main(String[] args) {
//大根堆PriorityQueue<Integer> maxHeap = new PriorityQueue<>(new IntBig());maxHeap.offer(1);maxHeap.offer(2);System.out.println(maxHeap.peek());}
}
//2

3.PriorityQueue常用接口介绍

构造器功能介绍
PriorityQueue()创建一个空的优先级队列,默认容量是11
PriorityQueue(intinitialCapacity)创建一个初始容量为initialCapacity的优先级队列,注意:
initialCapacity不能小于1,否则会抛IllegalArgumentException异
PriorityQueue(Collection<? extends E> c)用一个集合来创建优先级队列

4.PriorityQueue常用方法 

函数名功能介绍
boolean offer(E e)插入元素e,插入成功返回true,如果e对象为空,抛出NullPointerException异常,时
间复杂度 ,注意:空间不够时候会进行扩容
E peek()获取优先级最高的元素,如果优先级队列为空,返回null
E poll()移除优先级最高的元素并返回,如果优先级队列为空,返回null
int size()获取有效元素的个数
void clear()清空
boolean isEmpty()检测优先级队列是否为空,空返回true

 5.堆排序

1. 建堆
升序:建大堆
降序:建小堆
2. 利用堆删除思想来进行排序

//降序  public void headSort() {int end = useSized - 1;while(end > 0) {swap(elem,0,end);siftDown(0,end);end--;}}

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

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

相关文章

python中,try-except捕获异常的意义(通过ai智库学习)

python中&#xff0c;不但可以用try-except捕获异常&#xff0c; 还可以自定义异常提示字符串&#xff0c;更可以自定义捕获异常后的处置。 (笔记模板由python脚本于2024年10月03日 06:47:06创建&#xff0c;本篇笔记适合喜欢研究python的coder翻阅) 【学习的细节是欢悦的历程】…

基于SSM车位租赁系统【附源码】

基于SSM车位租赁系统 效果如下&#xff1a; 注册页面 首页展示 车位租赁订单展示 车位列表页面 公告信息管理页面 公告类型管理界面 研究背景 随着经济的持续增长和城市化进程的加速&#xff0c;土地资源变得日益紧缺&#xff0c;停车难问题已成为许多城市面临的共同挑战。随…

【JavaEE】——文件IO

阿华代码&#xff0c;不是逆风&#xff0c;就是我疯 你们的点赞收藏是我前进最大的动力&#xff01;&#xff01; 希望本文内容能够帮助到你&#xff01;&#xff01; 目录 一&#xff1a;认识文件 1&#xff1a;文件的概念 2&#xff1a;文件的结构 3&#xff1a;文件路径…

No package nodejs available.No package npm available.

安装nodejs时出现的报错 这个错误的原因是当前的 yum 源没有包含 Node.js 和 npm 的安装包。 解决方法 使用 NodeSource 仓库 curl -fsSL https://rpm.nodesource.com/setup_14.x | bash -运行 yum install 安装 Node.js 和 npm&#xff1a; yum install -y nodejs使用 E…

登录注册静态网页实现(HTML,CSS)

实现效果图 实现效果 使用HTML编写页面结构&#xff0c;CSS美化界面&#xff0c;点击注册&#xff0c;跳转到注册界面&#xff0c;均为静态网页&#xff0c;是课上的一个小作业~ 使用正则表达式对输入进行验证&#xff0c;包括邮箱格式验证&#xff0c;用户名格式验证。 正则…

YOLO 二元分类器

YOLO 二元分类器 在评估二元分类器性能时&#xff0c;TP、FP、TN和FN是四个核心指标&#xff0c;它们分别代表真阳性、假阳性、真阴性和假阴性。以下是这些指标的定义、计算方法以及在实际应用中的意义&#xff1a; 定义 TP&#xff08;真阳性&#xff09;&#xff1a;模型正…

嵌入式 c 内存堆栈增长方向往低地址方向好处

如下是堆和栈内存空间使用方式有如下好处&#xff1a; 1、stack从高地址向低地址扩展&#xff0c;这样栈空间的起始位置就能确定下来&#xff1b;如果反向&#xff0c;则要考虑这个起点从哪里合适&#xff0c;要确定堆的大小。 2、可以共用中间部分区域空间&#xff0c;最大化…

kafka-windows集群部署

kafka-windows集群部署目录 文章目录 kafka-windows集群部署目录前言一、复制出来四个kafka文件夹二、修改集群每个kafka的配置文件四、启动zookeeper&#xff0c;kafka集群 前言 部署本文步骤可以先阅读这一篇博客&#xff0c;这篇是关于单机kafka部署测试的。本文用到的文件…

Linux驱动学习——内核编译

1、从官网下载适合板子的Linux内核版本 选择什么版本的内核需要根据所使用的硬件平台而定&#xff0c;最好使用硬件厂商推荐使用的版本 https://www.kernel.org/pub/linux/kernel/ 2、将压缩包复制到Ubuntu内进行解压 sudo tar -xvf linux-2.6.32.2-mini2440-20150709.tgz 然…

职场上的人情世故,你知多少?这五点一定要了解

职场是一个由人组成的复杂社交网络&#xff0c;人情世故在其中起着至关重要的作用。良好的人际关系可以帮助我们更好地融入团队&#xff0c;提升工作效率&#xff0c;甚至影响职业发展。在职场中&#xff0c;我们需要了解一些关键要素&#xff0c;以更好地处理人际关系&#xf…

前端练习小项目 —— 让图片变得更 “色”

前言&#xff1a;相信读者在学习完了HTML、CSS和JavaScript之后已经想要迫不及待的想找一个小型的项目来练练手&#xff0c;那么这篇文章就正好能满足你的 “需求”。 ✨✨✨这里是秋刀鱼不做梦的BLOG ✨✨✨想要了解更多内容可以访问我的主页秋刀鱼不做梦-CSDN博客 在开始学习…

详解JavaScript中函数式编程

函数式编程 JS并非函数式编程语言&#xff0c;但可以应用函数式编程技术&#xff0c;这种风格很多语言都用&#xff0c;例如Java. 使用函数处理数组 假设有一个数组&#xff0c;数组元素都是数字&#xff0c;我们想要计算这些元素的平均值和标准差。使用非函数式编程风格的话…

微信小程序python+uniapp毕业论文选题系统设计与实现 lj141

目录 项目介绍具体实现截图开发者工具介绍技术路线性能/安全/负载方面开发语言以及框架介绍python-flask核心代码部分展示python-django核心代码部分展示详细视频演示源码获取 项目介绍 考虑到实际生活中在毕业论文选题管理方面的需要以及对该系统认真的分析,将小程序权限按管…

LabVIEW回转支承间隙自动化检测系统

开发了一种基于LabVIEW软件的回转支承间隙检测系统&#xff0c;通过高精度传感器和数据采集卡&#xff0c;自动化、高效地测量回转支承的轴向间隙和径向间隙&#xff0c;提高了检测精度和生产质量。以下是对系统的详细描述与应用案例分析&#xff0c;希望能为有类似需求的开发者…

linux如何与网络时间对齐(雪花算法ID重复)

文章目录 前言一、可能引发什么问题&#xff1f;二、调整步骤1.查看当前系统时间2.修改为中国时区3.同步网络时间4. 雪花id重复 总结 前言 linux服务器是部署服务的不二之选,有个小问题不可忽略&#xff1a; 会发现默认的服务器时间并非中国时区,时间也是相差八小时,中国时区…

踩坑NVTX

最开始在 【简说】NVTX Nsight Nvidia性能分析利器 看到NVTX的时候&#xff0c;我觉得这是一个好东西啊&#xff0c;可以详细说明每一段时间对应的是哪一段程序。 看了一下github&#xff0c;他的文章已经过时&#xff0c;现在已经不需要链接动态库了&#xff0c;直接includ…

2024_10_8 系统进展

改进位置 发现是label_api里藏了我需要改进的东西 settings.py 数据库 我这边电脑上使用的是windows 192 vue.config.js 陈家强是这样设置的 module.exports {publicPath: process.env.NODE_ENV production? /: /,assetsDir: static,// css: {// extract: false// },…

问:LINUXWINDOWS线程CPU时间如何排序?

Linux 在Linux上&#xff0c;你可以使用ps命令结合sort命令来查看和排序进程或线程的CPU使用时间。 查看进程的CPU使用时间并按时间排序 使用ps命令的-o选项可以自定义输出格式&#xff0c;-e选项表示显示所有进程&#xff0c;--sort选项用于排序。 ps -e -o pid,tid,comm,…

使用YOLO11实例分割模型进行人物分割【附完整源码】

《博主简介》 小伙伴们好&#xff0c;我是阿旭。专注于人工智能、AIGC、python、计算机视觉相关分享研究。 ✌更多学习资源&#xff0c;可关注公-仲-hao:【阿旭算法与机器学习】&#xff0c;共同学习交流~ &#x1f44d;感谢小伙伴们点赞、关注&#xff01; 《------往期经典推…

D31【python 接口自动化学习】- python基础之输入输出与文件操作

day31 文件的打开 学习日期&#xff1a;20241008 学习目标&#xff1a;输入输出与文件操作&#xfe63;-43 常见常新&#xff1a;文件的打开 学习笔记&#xff1a; 文件的概念 使用open()函数打开文件 文件路径处理 文件打开模式 总结 文件操作包括&#xff1a;打开&#…