优先级队列基础知识和模拟实现

1、概念:

优先级队列也是一种抽象数据类型。优先级队列中的每个元素都有优先级,而优先级高(或者低) 的将会出队,而优先级相同的则按照其在优先级队列中的顺序依次出队。常常有如下操作

  • 将对象添加到队列、删除最大、最小元素
  • 返回最高优先级对象
2、常用接口介绍

java 提供了 PriorityQueue 和 PriorityBlockingQueue 两种类型的优先级队列,其中后者是线程安全的,PriorityQueue 的效率会更好,以它来讲解。
1> 常用构造

PriorityQueue()		创建一个空的优先级队列,默认容量是 11
PriorityQueue(int initialCapacty)	创建一个初始容量为 initialCapacity的优先级队列
// 注意:initialCapacity 不能小于11,否则会抛出 illegalArgumentException 异常
priorityQueue(Collection<? extends E> c)  用一个集合来创建优先级队列

2> 添加/删除/获取优先级最高的元素

boolean offer(E e) // 添加元素 e,时间复杂度O(log2N),空间不够会扩容
E peek()		   // 获取优先级最高的元素,如果优先级队列为空,返回 null
E pool()		   // 移除优先级最高的元素并返回,如果优先级队列为空返回null
int size()		   // 获取有效元素的个数
void clear		   // 清空
boolean isEmpty()  // 见内测优先级队列是否为空
扩容方式,见源码:
private void grow(int minCapacity) {
	int oldCapacity = queue.length;
	// Double size if small; else grow by 50%
	int newCapacity = oldCapacity + ((oldCapacity < 64) ?
										(oldCapacity + 2) :
										(oldCapacity >> 1));
	// overflow-conscious code
	if (newCapacity - MAX_ARRAY_SIZE > 0)
		newCapacity = hugeCapacity(minCapacity);
	queue = Arrays.copyOf(queue, newCapacity);
}

如果小于 64 两倍+2的方式扩容,大于 641.5倍扩容
如果容量超过MAX_ARRAY_SIZE,按照MAX_ARRAY_SIZE来进行扩容
3.优先级队列的模拟实现

在JDK1.8 中的 PriorityQueue 底层用了堆这种数据结构,并且默认情况下是小堆,而堆是在完全二叉树的基础上进行了一些元素的调整。一下用堆模拟实现优先级队列:

public class MyPriorityQueue {
// 不再考虑扩容部分的代码
	private int[] array = new int[100];
	private int size = 0;
	public void offer(int e) {
		array[size++] = e;
		shiftUp(size - 1);
	}
	public int poll() {
		int oldValue = array[0];
		array[0] = array[--size];
		shiftDown(0);
		return oldValue;
	}
	public int peek() {
		return array[0];
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值