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

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


相关推荐

  • java中的四舍五入函数_java中进行四舍五入

    java中的四舍五入函数_java中进行四舍五入在oracle中有一个很好的函数进行四舍五入,round(),selectround(111112.23248987,6)fromdual;但是java的Number本身不提供四舍五入的方法,在oracle.jbo.domain.Number中提供了round()方法,也可以使用。在java中可以使用java.math.BigDecimal来进行四舍五入,或者直接使用DecimalForma…

    2022年5月21日
    72
  • 每天一道算法_2_求高精度幂

    今天这个可能有点偷懒,学c++的时候就知道大数计算很复杂,现在一直用java,有幸有大数的方法可以用那么今天的算法就用java偷懒过去吧Description对数值很大、精度很高的数进行高精度计算是一类十分常见的问题。比如,对国债进行计算就是属于这类问题。 现在要你解决的问题是:对一个实数R( 0.0 n),其中n 是整数并且 0 InputT输入包括多组 R 和 n。

    2022年3月10日
    41
  • python清理浏览器缓存_以编程方式清除边缘浏览器缓存

    python清理浏览器缓存_以编程方式清除边缘浏览器缓存我已经尝试这么做了好几天,并在堆栈溢出和许多其他网站没有运气。在基本上,我需要清除MicrosoftEdgeBrowser的缓存和Internet临时文件。我已经在我自己的电脑上找到了这个文件夹的位置,但是路径在每台电脑上都会动态变化。我不能每次都让程序清除相同的路径,因为路径会随每次安装而变化。在以下是缓存中的文件示例:C:\Users\patdj\AppData\Local\Package…

    2022年7月18日
    17
  • 557 原型prototype和原型链__proto__:原理,函数的三种角色,for in,手写new

    557 原型prototype和原型链__proto__:原理,函数的三种角色,for in,手写new向对象底层运行机制的三句话*面向对象底层运行机制的三句话:*1.每一个函数(普通函数、内置类/构造函数、自定义类/构造函数)都具备一个属性:prototype[原型],属性值是一个对象[浏览

    2022年7月3日
    19
  • Linux Platform Device and Driver「建议收藏」

    Linux Platform Device and Driver「建议收藏」 从Linux2.6起引入了一套新的驱动管理和注册机制:Platform_device和Platform_driver。Linux中大部分的设备驱动,都可以使用这套机制, 设备用Platform_device表示,驱动用Platform_driver进行注册。 Linuxplatformdriver机制和传统的devicedriver 机制(通过driver_registe

    2022年7月24日
    11
  • postgresql的ALTER经常使用操作

    postgresql的ALTER经常使用操作

    2022年2月6日
    52

发表回复

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

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