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

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


相关推荐

  • 在vscode中安装python第三方库

    在vscode中安装python第三方库打开vscode,点击终端,选择新建终端在弹出的窗口中输入以下命令:pipinstall第三方库的名称以安装numpy为例,输入pipinstallnumpy,点击回车,安装成功之后会显示如下信息:Requirementalreadysatisfied:numpyind:\python\lib\site-packages(1.20.3)已经满足的需求:numpy在d:python\lib\site-packages(1.20.3)…

    2022年10月7日
    0
  • springboot整合dubbo+zookeeper

    springboot整合dubbo+zookeeperspringboot整合dubbo+zookeeper项目结构:注意:在做此demo之前应该先自行搭建好zookeeper环境也可以搭建dubbo监控环境1.随便创建一个项目,之后添加一个maven项目用于存放接口packagecom.wzb.service;/***@authorSatsuki*@time2019/8/2717:51*@descripti…

    2022年10月21日
    1
  • 网页死链检测方法「建议收藏」

    网页死链检测方法「建议收藏」 了解测试方法之前,先了解下死链、链接的相关概念死链的种类协议死链:页面的TCP协议状态/HTTP协议状态明确表示的死链, 常见的如404、403、503状态等。 内容死链:服务器返回状态是正常的, 但内容已经变更 为不存在、已删除或需要权限等与原内容无关的信息页面。死链出现的原因网站目录更换。 服务器里某个文件移动了位置或者删除。 网站服务器设置错误。 动态链接在数据…

    2022年7月23日
    34
  • Android物联网应用程序开发(智慧城市)—— 摄像头监控界面开发「建议收藏」

    Android物联网应用程序开发(智慧城市)—— 摄像头监控界面开发「建议收藏」效果:布局代码:<?xmlversion=”1.0″encoding=”utf-8″?><RelativeLayoutxmlns:android=”http://schemas.android.com/apk/res/android”xmlns:app=”http://schemas.android.com/apk/res-auto”xmlns:tools=”http://schemas.android.com/tools”android

    2022年6月18日
    23
  • Android使用ViewPager实现左右循环滑动及轮播效果

    边界的时候会看到一个不能翻页的动画,可能影响用户体验。此外,某些区域性的ViewPager(例如展示广告或者公告之类的ViewPager),可能需要自动轮播的效果,即用户在不用滑动的情况下就能够看到其

    2021年12月27日
    45
  • HTML5实战与剖析之HTMLDocument变化(readyreState属性、兼容模式和head属性)「建议收藏」

    HTML5实战与剖析之HTMLDocument变化(readyreState属性、兼容模式和head属性)「建议收藏」之前为大家介绍了些许关于HTML5新添加的小东东,想必大家也有所了解了。今天为大家介绍HTML5中有关HTMLDocument方面新添加的内容。那么HTML5中有关HTMLDocument方面新添加的内容都有什么呢?HTML5中有关HTMLDocument方面新添加的内容有readyState属性、兼容模式判断和head属性。下面就为大家一一介绍这些新添加的小东东吧。

    2022年7月19日
    18

发表回复

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

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