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

优先队列的数据结构_低优先级队列一天只能一场目录一.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)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 反射型XSS的利用「建议收藏」

    反射型XSS的利用「建议收藏」反射型XSS:用户输入的恶意代码,被执行。利用:它通过给别人发送带有恶意脚本代码参数的URL,当URL地址被打开时,特有的恶意代码参数被HTML解析、执行。它的特点是非持久化,必须用户点击带有特定参数的链接才能引起。以前一直觉得反射型XSS危害不大,只能自己在客户端玩玩,实现弹窗。没想到,反射型XSS的利用比存储型还更容易,存储型XSS的利用还需结合CSRF.这篇博客很好的讲述了反射型XS…

    2022年5月4日
    97
  • 移动web开发总结

    让网页的宽度自适应屏幕<meta name="viewport" content="width=device-width"/>

    2021年12月22日
    41
  • 一篇文章带你搞懂DEX文件的结构[通俗易懂]

    一篇文章带你搞懂DEX文件的结构[通俗易懂]*本篇文章已授权微信公众号guolin_blog(郭霖)独家发布本文地址:一篇文章带你搞懂DEX文件的结构DEX文件就是AndroidDalvik虚拟机运行的程序,关于DEX文件的结构的重要性我就不多说了。下面,开练!建议:不要只看,跟着我做。看再多遍不如自己亲自实践一遍来的可靠,别问我为什么知道。泪崩ing…..首先,我们需要自己构造一个dex文件,因为自己构造的比…

    2022年6月27日
    156
  • MATLAB矩阵合并「建议收藏」

    MATLAB矩阵合并「建议收藏」两个或多个矩阵的拼接(合并)操作:学习链接用[]做拼接时,有三种连接符:逗号(,),空格,分号(;)。逗号(,)和空格等价,表示不换行,直接横向拼接,横向拼接要求两个矩阵行数相同;分号(;)表示换行后纵向拼接,纵向拼接要求两个拼接的矩阵的列数相同。代码展示:1.横向拼接:1%逗号和空格表示横向拼接2A=zeros(4,2)3B=ones(4,1)4C=[AB]A=00000000B=11

    2022年6月25日
    118
  • 动态规划经典题目汇总图_离散型动态规划经典题目

    动态规划经典题目汇总图_离散型动态规划经典题目http://www.cppblog.com/doer-xee/archive/2009/12/05/102629.html转载之前先Orz一下:[s:19]Robberies http://acm.hdu.edu.cn/showproblem.php?pid=2955背包;第一次做的时候把概率当做背包(放大100000倍化为整数):在此范围内最多能抢多少钱 最脑残的是把总

    2025年7月9日
    2
  • 超详细总结之Word2Vec(一)原理推导[通俗易懂]

    超详细总结之Word2Vec(一)原理推导[通俗易懂]本章是介绍Word2Vec的原理推导部分,后面还会有基于TensorFlow的Word2Vec代码实现讲解。一、什么是Word2Vec?2013年,Google团队发表了word2vec工具。word2vec工具主要包含两个模型:跳字模型(skip-gram)和连续词袋模型(continuousbagofwords,简称CBOW),以及两种高效训练的方法:负采样(negatives…

    2022年5月17日
    33

发表回复

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

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