优先级队列之PriorityQueue

前言:优先级队列的实现有很多,PriorityQueue只是其中之一。

1. PriorityQueue

1.1 简介

  1. Queue接口:该接口规定了只能一头进,另一头出,并没有规定出的逻辑。【注意:java中并没有专门实现先进先出的类,要实现先进先出逻辑,可以使用双端队列Queue】
  2. PriorityQueue:继承了Queue接口,其继承的是队列的进出操作,该类的出逻辑为优先级最高的出队列。
  3. 底层结构:PriorityQueue底层采用的堆实现。【堆的相关知识点】
  4. 安全性:Java集合框架中提供了PriorityQueuePriorityBlockingQueue两种类型的优先级队列。前者是线程不安全的,后者是线程安全的。
  5. 细节:
    1. 优先级导致有序特性,故和 TreeMap[点击查看详情] 一样,在使用PriorityQueue一定要有排序规则:
      ① 要么 在添加元素时,要添加元素实现了Compareable接口 (比如String、Integer都是从小到大排序)
      ② 要么 在创建PriorityQueue对象时,传入比较器Comparator。
    2. 不能插入 null 对象,否则会抛出 NullPointerException 异常。
    3. 进和出的时间复杂度均为 O(log2N)
    4. 对于remove(Object)和contains(Object)方法是线性时间 O(n)

1.2 构造器

PriorityQueue()初始容量(11),自然排序
PriorityQueue(Comparator<? super E> comparator)初始容量(11),根据比较器排序
PriorityQueue(int initialCapacity)指定初始容量,自然排序
PriorityQueue(int initialCapacity,Comparator comparator)指定初始容量,根据比较器排序
PriorityQueue(PriorityQueue c)创建队列,并复制传入的队列元素,并使用传入的队列的排序方式
PriorityQueue(SortedSet c)创建队列,并复制传入的SortedSet元素,并使用传入的SortedSet的排序方式

1.3 常用方法

错误处理抛出异常返回false、null
add(e)boolean offer(e)
出并返回删除元素remove()<?> poll()
查看队首元素element()<?> peek()
clear()清空整个列队
contains(Object o)检查是否包含当前参数元素,返回布尔类型
remove(Object o)根据value删除指定元素
size()返回元素个数
isEmpty()判断队列是否为空,返回布尔类型
Object [] toArray()将队列中所有元素的放入运行类型为Object的数组中,并返回
T[] toArray(T[] a)将队列中所有元素的放入传入的数组中,并返回

2. 扩容机制

private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
    private void grow(int minCapacity) {
        int oldCapacity = queue.length;
        
        int newCapacity = oldCapacity + ((oldCapacity < 64) ? (oldCapacity + 2): (oldCapacity >> 1));

        if (newCapacity - MAX_ARRAY_SIZE > 0) {
            newCapacity = hugeCapacity(minCapacity);
        }

        queue = Arrays.copyOf(queue,newCapacity);
    }

易知,自动扩容机制:

  1. 如果容量 < 64,按照 oldCapacity * 2 + 2 进行扩容。
  2. 如果容量 >= 64,按照 oldCapacity * 1.5 进行扩容
  3. 如果容量超过 MAX_ARRAY_SIZE,按照 MAX_ARRAY_SIZE 进行扩容

3. 关于遍历

PriorityQueue的iterator()不保证由小到大或由大到小输出。若想按大小顺序遍历,可以先将队列转成数组,然后排序遍历。

public static void main(String[] args) {
        Queue<Integer> q = new PriorityQueue<>(new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                if (o1 > o2)
                    return 1;
                else if (o1 == o2) {
                    return 0;
                } else {
                    return -1;
                }
            }
        });

        int[] nums= {2,5,3,4,1,6};
        for (int num : nums) {
            q.add(num);
        }
        Integer[] numss = q.toArray(new Integer[nums.length]);
        // 从小到大
        System.out.println(Arrays.toString(numss));
        // 从大到小
        Arrays.sort(numss, new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return o2 - o1;
            }
        });
        System.out.println(Arrays.toString(numss));
    }

输出:在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ElegantCodingWH

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值