优先队列的数据结构_低优先级队列一天只能一场

优先队列的数据结构_低优先级队列一天只能一场目录一.PriorityQueuePriorityQueue简介继承关系PriorityQueue示例二.Comparable比较器Compara接口三.Comparator比较器Comparator接口四.底层原理一.PriorityQueuePriorityQueue简介PriorityQueue,即优先级队列。优先级队列可以保证每次取出来的元素都是队列中的最小或最大的元素<Java优先级队列默认每次取出来的为最小元素&gt.

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

目录

一. PriorityQueue

PriorityQueue 简介

继承关系

PriorityQueue 示例

二. Comparable 比较器

Compare 接口

三. Comparator 比较器

Comparator 接口

四. 底层原理


一. PriorityQueue

PriorityQueue 简介

PriorityQueue ,即优先级队列。优先级队列可以保证每次取出来的元素都是队列中的最小最大的元素<Java优先级队列默认每次取出来的为最小元素>。

大小关系:元素的比较可以通过元素本身进行自然排序,也可以通过构造方法传入比较器进行比较。

继承关系

优先队列的数据结构_低优先级队列一天只能一场

通过继承关系图可以知道 PriorityQueueQueue 接口的一个实现类,而 Queue 接口是 Collection 接口的一个实现类,因此其拥有 Collection 接口的基本操作,此外,队列还提供了其他的插入,移除和查询的操作。每个方法存在两种形式:一种是抛出异常(操作失败时),另一种是返回一个特殊值(null 或 false)。

优先队列的数据结构_低优先级队列一天只能一场

 PriorityQueuepeekelement 操作的时间复杂度都为常数,add,offer,remove 以及 poll 的时间复杂度是 log(n)。

PriorityQueue 示例

impot java.util.PriorityQueue;

public class PriorityQueueTest{
    public static void main(String[] args){
        PriorityQueue<Integer> queue = new PriorityQueue<>();
        queue.add(11);
        queue.add(22);
        queue.add(33);
        queue.add(55);
        queue.add(44);
        System.out.println(queue.remove());
        System.out.println(queue.remove());
        System.out.println(queue.remove());
        System.out.println(queue.remove());
        System.out.println(queue.remove());
    }
}

运行结果:

优先队列的数据结构_低优先级队列一天只能一场

代码中我们依次添加11,22,33,55,44五个数据,然后进行删除,通过结果我们发现,每次删除的都为队列中最小元素,即体现了优先级队列。

结论:优先级队列默认每次获取队列最小的元素,也可以通过 comparator 比较器来自定义每次获取为最小还是最大。

注意:优先级队列中不可以存储 null

二. Comparable 比较器

Compare 接口

public interface Comparable<T>{
    public int compareTo(T o);
}

该接口只存在一个 public int compareTo(T o); 方法,该方法表示所在的对象和 o 对象进行比较,返回值分三种:

1:表示该对象大于 o 对象

0:表示该对象等于 o 对象

-1:表示该对象小于 o 对象

需求:在优先级队列中存储对象学生,每个学生有 id,name 两个属性,并且使优先级队列每次按照学生的 id 从小到大取出。

代码示例:

Student 类:当前类实现了 Comparable 接口,即当前类提供了默认的比较方法。

    public class Student implements Comparable{
        private int id;
        private String name;
        
        public Student(int id,String name,int age){
            this.id = id;
            this.name = name;
        }
        
        public int getId(){
            return id;
        }
        
        @Override
        public String toString(){
            return "Student{" +
                    "id=" + id +
                    ", name='" + name + '\'' +
                    '}';
        }
        
        @Override
        public int compareTo(Object o){
            Student o1 = (Student)o;
            return this.id - o1.id;
        }
    }

PriorityQueueTest 类:

public class PriorityQueueTest {
    public static void main(String[] args) {
        PriorityQueue<Student> queue = new PriorityQueue<>();
        queue.add(new Student(2,"Jack"));
        queue.add(new Student(1,"Mary"));
        queue.add(new Student(5,"Mcan"));
        queue.add(new Student(4,"Scolt"));
        queue.add(new Student(3,"Tina"));
        System.out.println(queue.remove());
        System.out.println(queue.remove());
        System.out.println(queue.remove());
        System.out.println(queue.remove());
        System.out.println(queue.remove());
    }
}

运行结果:

优先队列的数据结构_低优先级队列一天只能一场

三. Comparator 比较器

新需求:如果使优先级队列按照学生 id 从大到小取出呢?我们很快就会想到修改 Student 类的compareTo 方法,使 return o1.id – this.id;这样当然可以实现我们的新需求。但是有很多时候类的compareTo 方法是不能修改的,比如 JDK 给我们提供的源代码,在不修改 compareTo 方法的前提下实现需求,只能用 comparator 比较器了。

Comparator 接口

public interface Comparator<T>{
    int compare(T o1,T o2);
}

该接口只存在一个 int compare(T o1,T o2);方法,该方法需要参数是两个待比较的对象,返回结果是 int 类型:

1:表示 o1对象 大于 o2 对象

0:表示 o1对象 等于 o2 对象

-1:表示 o1对象 小于 o2 对象

public class PriorityQueueTest {
    public static void main(String[] args) {
        PriorityQueue<Student> queue = new PriorityQueue<>(new Comparator<Student>() {

            @Override
            public int compare(Student o1, Student o2) {
                return o2.getId() - o1.getId();
        }
    })
    queue.add(new Student(2, "Jack"));
    queue.add(new Student(1, "Mary"));
    queue.add(new Student(5, "Mcan"));
    queue.add(new Student(4, "Scolt"));
    queue.add(new Student(3, "Tina"));
    System.out.println(queue.remove());
    System.out.println(queue.remove());
    System.out.println(queue.remove());
    System.out.println(queue.remove());
    System.out.println(queue.remove());
}
}

运行结果:

优先队列的数据结构_低优先级队列一天只能一场

四. 底层原理

优先级队列是如何保证每次取出的是队列中最小(最大)的元素的呢?查看源代码,底层的存储结构为一个数组

transient Object[] queue;

表面上是一个数组结构,实际上优先队列采用的是堆的形式来进行存储的,通过调整小堆大堆保证每次取出的元素为队列中的最小或最大。

详见:https://blog.csdn.net/Lucky_mzc/article/details/123331280?spm=1001.2014.3001.5501

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/190435.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 关系数据库理论(一)

    关系数据库理论(一)前面已经讲述了关系数据库、关系模型的基本概念以及关系数据库的标准语言。如何使用关系模型设计关系数据库,也就是面对一个现实问题,如何选择一个比较好的关系模式的集合,每个关系又应该由哪些属性组成,这属于数

    2022年7月1日
    27
  • presto timestmp使用

    presto timestmp使用

    2021年11月27日
    57
  • 华硕老毛子Padavan使用IPV6+Aliddns远程管理路由

    华硕老毛子Padavan使用IPV6+Aliddns远程管理路由华硕老毛子Padavan使用IPV6远程管理路由前言一、pandas是什么?二、使用步骤1.引入库2.读入数据总结前言提示:以下是本篇文章正文内容,下面案例可供参考一、pandas是什么?示例:pandas是基于NumPy的一种工具,该工具是为了解决数据分析任务而创建的。二、使用步骤1.引入库代码如下(示例):importnumpyasnpimportpandasaspdimportmatplotlib.pyplotaspltimportseaborna

    2022年6月5日
    520
  • Weblogic-SSRF漏洞复现

    Weblogic-SSRF漏洞复现这两天了解的ssrf复现这个漏洞差不多了,开始进行笔迹整理:上面一篇介绍的就是些入门的基础,让你可以更加好的去理解,更好的懂ssrf这个漏洞的原理。0x00到底什么是ssrf呢?SSRF(server-siderequestforgery):服务器端请求伪造。是一种由攻击者构造形成由服务器端发起请求的一个安全漏洞,一般情况下,ssrf攻击的目标是从外网无法访问的内部系统(正是因…

    2022年6月25日
    51
  • 2022最新Java面试宝典(史上最全,BAT大厂面试必备,用心看完该篇就够了,建议先关注点赞加收藏)

    2022最新Java面试宝典(史上最全,BAT大厂面试必备,用心看完该篇就够了,建议先关注点赞加收藏)史上最全Java面试宝典,BAT大厂必备,建议先点赞收藏,内容持续更新中。。。。序号名称地址1Java基础面试题2Java并发编程面试题3Java异常面试题4Java虚拟机(JVM)面试题5Java集合面试题6Linux面试题7Memcache面试题8Mybatiss面试题9MySQL面试题10Netty面试题11Nginx面试题12RabbitMQ面试题13Re

    2026年2月1日
    9
  • android设计个人简历页面_Android程序员个人简历模板下载(Word格式)[通俗易懂]

    android设计个人简历页面_Android程序员个人简历模板下载(Word格式)[通俗易懂]求职意向:Android程序员熟悉Android系统体系结构和软件开发技术,熟悉Eclipse集成开发环境以及Git代码管理工具;熟悉网络通信协议Http,Socket编程,XMPP协议以及JSON数据解析;熟悉Android程序开发,熟悉四大组件、常用UI组件、多线程等操作及原理;熟练掌握SQLite数据库、SharedPreferences以及文件存储等存储方式;衷情于互联网技术应用。XXXX…

    2022年4月28日
    122

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号