数据结构之优先级队列

优先级队列是一种特殊的数据结构,基于堆实现,支持按优先级出队。它不允许插入不可比较的元素和null,提供offer、peek、poll等方法,并在插入和删除时保持O(logN)的时间复杂度。优先级队列常用于解决top-k问题,如找出数组中最小的k个数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

优先级队列

概念

队列是一种先进先出(FIFO)的数据结构。
但在有些情况下,我们进行操作的数据可能带有优先级,在出队列时可能需要优先级高的先出队列。因此,把具有返回优先级最高的对象和添加新对象操作的数据结构称为优先级队列(PriorityQueue)。

基本特性

  1. 使用时必须导入PriorityQueue所在的包:
import java.util.PriorityQueue;
  1. PriorityQueue中存放的元素必须是能够比较大小的,不能插入无法比较大小的对象,否则会抛异常。
  2. 不能插入null对象,否则会跑出空指针异常。
  3. 没有容量限制,可以插入任意多个元素,其内部可以自动进行扩容。
  4. 插入和删除元素的时间复杂度为O(logN)。
  5. PriorityQueue的底层结构使用了堆数据结构。(用数组存储数据
    用树来组织数据)
  6. 常见的优先级队列的构造方法:
    在这里插入图片描述
    代码示例:
public static void TestPriorityQueue(){
	// 创建一个空的优先级队列,底层默认容量是11
	PriorityQueue<Integer> q1 = new PriorityQueue<>();
	// 创建一个空的优先级队列,底层的容量为initialCapacity
	PriorityQueue<Integer> q2 = new PriorityQueue<>(100);
	ArrayList<Integer> list = new ArrayList<>();
	list.add(4);
	list.add(3);
	list.add(2);
	list.add(1);
	// 用ArrayList对象来构造一个优先级队列的对象
	// q3中已经包含了三个元素
	PriorityQueue<Integer> q3 = new PriorityQueue<>(list);
	System.out.println(q3.size());
	System.out.println(q3.peek());
}

默认情.况下,PriorityQueue队列底层默认容量是11.

  1. 优先级队列的扩容方式:
  • 如果容量小于64时,按照oldCapacity*2+2的方式扩容。
  • 如果容量大于等于64,按照oldCapacity*1.5的方式扩容。
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);
}
private static int hugeCapacity(int minCapacity) {
    if (minCapacity < 0) // overflow
        throw new OutOfMemoryError();
    return (minCapacity > MAX_ARRAY_SIZE) ?
        Integer.MAX_VALUE : MAX_ARRAY_SIZE;
}
  1. 常用方法:
  • boolean offer(E e) :插入元素e,插入成功返回true,如果e对象为空,抛出异常,时间复杂度O(logN) ,注意:空间不够时候会进行扩容
  • E peek() :获取优先级最高的元素,如果优先级队列为空,返回null
  • E poll() :移除优先级最高的元素并返回,如果优先级队列为空,返回null
  • int size() :获取有效元素的个数
  • void clear(): 清空
  • boolean isEmpty() :检测优先级队列是否为空,空返回true
  1. 优先级队列的应用:top-k问题
    例如:
    设计一个算法,找出数组中最小的k个数。以任意顺序返回这k个数均可。
public int[] smallK(int[] arr,int k){
	if(arr==null||k<=0){
		return new int[0];
	}
	PriorityQueue<Integer> p = new PriorityQueue<>();
	for(int i = 0;i < arr.length;i++){
		p.offer(arr[i]);
	}
	int[] ret = new int[k];
	for(int i = 0;i < k;i++){
		ret[i] = p.poll();
	}
	return ret;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值