堆-优先队列priorityqueue原理和应用

news2024/9/24 17:35:16

java中PriorityQueue优先队列
优先队列 :底层是用数组实现的二叉堆,因为堆通常分为大顶堆或者小顶堆,所以优先队列可以获取每次出来的都是最大或者最小元素(对象可以实现比较器,Java优先级队列默认每次取出来的为最小元素)。
因为底层实现是数据结构堆,所以其时间复杂度peek和element操作的时间复杂度都为常数,
add、offer、remove以及poll的时间复杂度是log(n)。

底层原理:

优先队列底层实际是用数组实现的二叉堆
优先级队列表示为一个平衡的二进制堆:队列[n]的两个子队列是队列[2n+1]和队列[2(n+1)]。优先级队列根据比较器排序,或者如果比较器为空,则根据元素的自然顺序排序:
在这里插入图片描述
对于堆的实现是基于数组来实现的,实际开辟存储空间是数组,对数据的访问按照二叉树来进行访问遍历。父节点和子节点编号存在联系,父节点和子节点存在如下关系:
Arr[(i-1)/2] Returns the parent node
Arr[(2i)+1] Returns the left child node
Arr[(2
i)+2] Returns the right child node
以小根堆为例,数据如何进行调整:
插入数据
入数据首先在有效数据的最后一个位置,即插入在某个叶子节点上,以该节点为待调整节点,和其父节点比较,如果当前节点大于父节点,符合小根堆,不用进行调整,否则需要进行调整,调整至0号根节点或者是其中某一个位置时当前节点大于父节点才终止。

在这里插入图片描述
源码:

public boolean offer(E e) {
    if (e == null)
        throw new NullPointerException();
    modCount++;
    int i = size;
    if (i >= queue.length)
        grow(i + 1);
    size = i + 1;
    if (i == 0)
        queue[0] = e;
    else
        siftUp(i, e);
    return true;
}

private void siftUp(int k, E x) {
    if (comparator != null)
        siftUpUsingComparator(k, x);
    else
        siftUpComparable(k, x);
}

@SuppressWarnings("unchecked")
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;
}

删除数据
因为是小根堆,其堆顶元素最小,所以删除的为堆顶的元素。删除堆顶元素过程,首先记录0号下标的位置,并用最后一个元素替换0号下标的元素,当前的小根堆可能被破坏,需要对堆进行调整,从k指定的位置开始,将逐层向下与当前的左右孩子中较小的进行交换,直到x小于或者等于左右孩子中的任何一个为止。
源码

在这里插入图片描述

public E poll() {
    if (size == 0)
        return null;
    int s = --size;
    modCount++;
    E result = (E) queue[0];
    E x = (E) queue[s];
    queue[s] = null;
    if (s != 0)
        siftDown(0, x);
    return result;
}
private void siftDown(int k, E x) {
    if (comparator != null)
        siftDownUsingComparator(k, x);
    else
        siftDownComparable(k, x);
}

@SuppressWarnings("unchecked")
private void siftDownComparable(int k, E x) {
    Comparable<? super E> key = (Comparable<? super E>)x;
    int half = size >>> 1;        // loop while a non-leaf
    while (k < half) {
        int child = (k << 1) + 1; // assume left child is least
        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;
}

应用

集合排序


```java
package com.example.demo.suanfa.binary.heap;

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

public class HeapTest {
    public static void main(String[] args) {
        Queue<Integer> queue = new PriorityQueue<>();
        queue.add(2);
        queue.add(10);
        queue.add(1);
        queue.add(5);
        queue.add(7);
        queue.add(8);
        System.out.print(queue.remove()+" ");
        System.out.print(queue.remove()+" ");
        System.out.print(queue.remove()+" ");
        System.out.print(queue.remove()+" ");
        System.out.print(queue.remove()+" ");
        System.out.print(queue.remove()+" ");
    }
}

执行返回
1 2 5 7 8 10 
Process finished with exit code 0


不可以加入null,因为无法比较,所有需要去除null
![在这里插入图片描述](https://img-blog.csdnimg.cn/c82a80393db146ca918f2ed178b0127b.png)
2.对象加入priorityQueue,需要有属性可以比较,并且实现比较接口Comparable,可实现从小到大排序和从大到小排序

```java
package com.example.demo.suanfa.binary.heap;

import org.springframework.cache.annotation.Cacheable;

public class Student implements Comparable {
    private int age;
    private String name;

    public Student(int age, String name) {
        this.age = age;
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

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


package com.example.demo.suanfa.binary.heap;

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

public class HeapTest {
    public static void main(String[] args) {
        Queue<Student> qStudent = new PriorityQueue<>();
        qStudent.offer(new Student(3,"小明"));
        qStudent.offer(new Student(2,"小红"));
        qStudent.offer(new Student(1,"小蓝"));
        System.out.println(qStudent.remove().getAge()+" " );
        System.out.println(qStudent.remove().getAge()+" " );
        System.out.println(qStudent.remove().getAge()+" " );
    }
}

执行返回 1 2 3

如果没有实现compare接口  报错

在这里插入图片描述

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

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

相关文章

RocketMQ-NameServer详解

RocketMQ 路由管理 服务注册及服务发现由NameServer提供。 服务发现&#xff1a; 分布式服务 SOA&#xff08;全称&#xff1a;Service Oriented Architecture 面向服务的架构&#xff09;构体系中会有服务注册中心&#xff0c;分布式服务 SOA 的注册中心主要提供服务调用的解析…

10套“2023年软考备考资料”送给你

距离软考考试越来越近了&#xff0c;备考的形势越发紧张了。考点那么多&#xff0c;我们需要抓出常考的大部分知识点。 ​为此&#xff0c;为大家整理了《2023年软考免费备考资料》&#xff0c;内含软考各科目不同类型共10套备考资料。 ​ 第1套&#xff1a;早鸟学习计划&am…

华为OD机试题,用 Java 解【密室逃生游戏】问题

最近更新的博客 华为OD机试 - 猴子爬山 | 机试题算法思路 【2023】华为OD机试 - 分糖果(Java) | 机试题算法思路 【2023】华为OD机试 - 非严格递增连续数字序列 | 机试题算法思路 【2023】华为OD机试 - 消消乐游戏(Java) | 机试题算法思路 【2023】华为OD机试 - 组成最大数…

使用matlab生成符合哈工大学报的图片格式

前言 去年投稿了哈尔滨工业大学学报&#xff0c;因为模板问题没有过于要求投稿的细节&#xff0c;所以出图都是按照自己的风格来的。录用前的最后要求时需要修改图片格式&#xff0c;具体是表示成函数图&#xff0c;并且横纵坐标保持相同的精确位数。我想那么多图片我咋搞呀&a…

Elasticsearch(一)——部署

最近遇到一个需求&#xff0c;需要用到Elasticsearch&#xff0c;于是开始学习Elasticsearch。 我是个学东西先学实操再理论的人。所以开始着手安装Elasticsearch&#xff0c;并进行记录。 目录一、Elasticsearch部署Windows安装1 下载2 解压3 配置文件3.1 jvm.options3.2 elas…

没有公网IP,如何实现内网用友ERP的外网访问 ?

用友是全球领先的企业云服务与软件提供商&#xff0c;在财务、人力、供应链、采购、制造、营销、研发、项目、资产、协同等领域为客户提供数字化、智能化、社会化的企业云服务产品与解决方案。 U8C是用友针对成长型、创新型企业&#xff0c;提供企业级ERP整体解决方案。在系统…

【软件测试】自动化测试的追求,水土不服?看看资深测试咋说的......

目录&#xff1a;导读前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09;前言 大部分测试初学者入…

mysql存储位置 、数据类型

在线版 mysql0.80 版本 数据库存放位置默认为:C:\ProgramData\MySQL\MySQL Server 8.0 mysql数据类型(来自黑马) 数据类型大小描述备注TINYINT1 byte小整数值SMALLINT2 bytes大整数值MEDIUMINT3 bytes大整数值INT或INTEGER4 bytes大整数值age intBIGINT8 bytes极大整数值F…

MQRabbitMQ

介绍 MQ&#xff0c;中文是消息队列&#xff08;MessageQueue&#xff09;&#xff0c;字面来看就是存放消息的队列。也就是事件驱动架构中的Broker。 几种常见MQ的对比 RabbitMQActiveMQRocketMQKafka公司/社区RabbitApache阿里Apache开发语言ErlangJavaJavaScala&Java…

车载开发知识交流【学习路线】

前言 在2023国内百废待兴&#xff1b;经济复苏的号召一直在响应&#xff0c;这对于压抑了三年的人民来说无疑是福音。这篇我们主要说一下拉动经济的其中大板块——车企&#xff1b;我们知道我们最大的经济除了房地产&#xff0c;第二就是车企。而在造车领域中也不断的加入了许…

CF1692C Where‘s the Bishop? 题解

CF1692C Wheres the Bishop? 题解题目链接字面描述题面翻译题目描述题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1提示代码实现题目 链接 https://www.luogu.com.cn/problem/CF1692C 字面描述 题面翻译 题目描述 有一个888\times888的棋盘&#xff0c;列编号从…

【Android视频号② 搜索用户】

上一节我们已经拿到了视频号个人主页信息 但是发现传过来的用户名是一个以V2开头的数据 接下来我们就需要根据用户名去获取V2数据 DDMS问题 上一节根据ddms 可以很好的定位到视频号触发点 但是很多人会遇到一个问题就是 Monitor 使用 如果打开报错 需要装Java1.8 版本太高了…

运维排查篇 | Linux 连接跟踪表满了怎么处理

nf_conntrack (在老版本的 Linux 内核中叫 ip_conntrack )是一个内核模块&#xff0c;用于跟踪一个网络连接的状态 一旦内核 netfilter 模块 conntrack 相关参数配置不合理&#xff0c;导致 nf_conntrack table full &#xff0c;就会出现丢包、连接无法建立的问题 这个问题其…

电子技术——反馈放大器的分析方法总结

电子技术——反馈放大器的分析方法总结 第一种也是最简单的估算方法&#xff0c;直接拿出反馈网络&#xff0c;计算 β\betaβ 则假设在 AβA\betaAβ 无限大的情况下有 Af≃1/βA_f \simeq 1/\betaAf​≃1/β 。开环法。比第一种方法更能精确的估计 AAA 和 β\betaβ 的值。系…

js的异步方法:promise与定时器相遇,碰到的火花

前言&#xff1a; 我们在项目中长使用的异步方法 promise与定时器 在一起后&#xff0c;他们的顺序是什么样呢&#xff1f;这里来说一说。 案例1&#xff1a; console.log(异步打印顺序&#xff1a;);console.log(1);setTimeout(()>{console.log(2);},2000)setTim…

APP 兼容性测试是什么?10年阿里测试老鸟告诉你......

1、APP 兼容性测试认识 随着 APP 应用范围越来越广&#xff0c;用户群体越来越大&#xff0c;终端设备的型号也越来越多&#xff0c;移动终端碎片化加剧&#xff0c;使得 APP 兼容性测试成为测试质量保障必须要考虑的环节。 APP 兼容性测试通常会考虑&#xff1a;操作系统、厂…

firefly开发板RK3588非默认外设使能(串口uart、IIC、adc等)设备树修改详细步骤

sdk获取和内核编译&#xff0c;参考上一篇博文&#xff1a;rk3588内核裁剪 一、相关文件 文件1&#xff1a; rk3588_repo_sdk_v1.0.2a/kernel/arch/arm64/boot/dts/rockchip/rk3588-firefly-itx-3588j.dtsi此文件是针对firefly的板级设备树文件。 文件2&#xff1a; rk3588…

C#底层库--MySQL数据库脚本构建类(自动构建insert、update)

系列文章 C#底层库–记录日志帮助类 本文链接&#xff1a;https://blog.csdn.net/youcheng_ge/article/details/124187709 C#底层库–MySQL数据库脚本构建器&#xff08;推荐阅读&#xff09; 本文链接&#xff1a;https://blog.csdn.net/youcheng_ge/article/details/129179…

华为云计算之远程复制

实验环境说明身份管理IP业务IP主设备192.168.43.50H2&#xff1a;192.168.43.55从设备192.168.43.100P2&#xff1a;192.168.43.105存储的管理端口为8088登录到存储设备查看是否导入License访问https://192.168.43.50:8088&#xff0c;登录到主设备在设置中查看是否有添加远程设…

【AI绘图学习笔记】生成函数

生成模型学习笔记 &#xff08;文章中大部分内容从网上学习笔记中摘录&#xff0c;推荐阅读原文&#xff0c;吴恩达深度学习课程笔记暂时停更一段时间&#xff0c;学习AI绘图原理是为了搞定毕业设计&#xff0c;等忙完再回头把基础补完&#xff0c;推荐读物《深度学习》花书&a…