java 实现优先级队列_自己动手实现java数据结构(八) 优先级队列

1.优先级队列介绍1.1 优先级队列有时在调度任务时,我们会想要先处理优先级更高的任务。例如,对于同一个柜台,在决定队列中下一个服务的用户时,总是倾向于优先服务VIP用户,而让普通用户等待,即使普通的用户是先加入队列的。优先级队列和普通的先进先出FIFO的队列类似,最大的不同在于,优先级队列中优先级最高的元素总是最先出队的,而不是遵循先进先出的顺序。1.2 堆优先级队列的接口要求很简单。从逻辑上来...
摘要由CSDN通过智能技术生成

1.优先级队列介绍

1.1 优先级队列

有时在调度任务时,我们会想要先处理优先级更高的任务。例如,对于同一个柜台,在决定队列中下一个服务的用户时,总是倾向于优先服务VIP用户,而让普通用户等待,即使普通的用户是先加入队列的。

优先级队列和普通的先进先出FIFO的队列类似,最大的不同在于,优先级队列中优先级最高的元素总是最先出队的,而不是遵循先进先出的顺序。

1.2 堆

优先级队列的接口要求很简单。从逻辑上来说,向量、链表或者平衡二叉搜索树等数据结构都可用于实现优先级队列。但考虑到时间和空间的效率,就必须仔细斟酌和考量了。而一种被称为堆的数据结构非常适合实现优先级队列。’

堆和二叉搜索树类似,存储的元素在逻辑上是按照层次排放的,在全局任意地方其上层元素优先级大于下层元素,这一顺序性也被称为堆序性,而其中优先级最大的元素被放在最高的层级(大顶堆)。和二叉搜索树的排序方式不同的是,堆中元素的顺序并不是完全的排序,而只是维护了一种偏序关系,被称为堆序性。在这种偏序关系下,元素之间的顺序性比较疏散,维护堆序性的代价比较低,因而在实现优先级队列时,堆的效率要高于平衡二叉搜索树。

1.3 完全二叉堆

完全二叉堆是堆的一种,其元素在逻辑上是以完全二叉树的形式存放的,但实际却是存储在向量(数组)中的。在这里,我们使用完全二叉堆来实现优先级队列。

3a34c58a499f67869d05e2da2afb08f0.png

2.优先级队列ADT接口

/*** 优先级队列 ADT接口*/

public interface PriorityQueue {/*** 插入新数据

*@paramnewData 新数据

**/

voidinsert(E newData);/*** 获得优先级最大值(窥视) 不删数据

*@return当前优先级最大的数据

**/E peekMax();/*** 获得并且删除当前优先级最大值

*@return被删除的 当前优先级最大的数据*/E popMax();/*** 获得当前优先级队列 元素个数

*@return当前优先级队列 元素个数

**/

intsize();/*** 是否为空

*@returntrue 队列为空

* false 队列不为空

**/

booleanisEmpty();

}

3.完全二叉堆实现细节

3.1 基础属性

完全二叉堆内部使用之前封装好的向量作为基础。和二叉搜索树类似,用户同样可以通过传入Comparator比较器来指定堆中优先级大小比较的逻辑。

public class CompleteBinaryHeap implements PriorityQueue{/*** 内部向量

**/

private ArrayListinnerArrayList;/*** 比较逻辑

**/

private final Comparatorcomparator;/*** 当前堆的逻辑大小

**/

private intsize;

构造方法:

/*** 无参构造函数

**/

publicCompleteBinaryHeap() {this.innerArrayList = new ArrayList<>();this.comparator = null;

}/*** 指定初始容量的构造函数

*@paramdefaultCapacity 指定的初始容量

**/

public CompleteBinaryHeap(intdefaultCapacity){this.innerArrayList = new ArrayList<>(defaultCapacity);this.comparator = null;

}/*** 指定初始容量的构造函数

*@paramcomparator 指定的比较器逻辑

**/

public CompleteBinaryHeap(Comparatorcomparator){this.innerArrayList = new ArrayList<>();this.comparator =comparator;

}/*** 指定初始容量和比较器的构造函数

*@paramdefaultCapacity 指定的初始容量

*@paramcomparator 指定的比较器逻辑

**/

public CompleteBinaryHeap(int defaultCapacity, Comparatorcomparator) {this.innerArrayList = new ArrayList<>(defaultCapacity);this.comparator =comparator;

}/*** 将指定数组 转换为一个完全二叉堆

*@paramarray 指定的数组

**/

publicCompleteBinaryHeap(E[] array){this.innerArrayList = new ArrayList<>(array);this.comparator = null;this.size =array.length;//批量建堆

heapify();

}/*** 将指定数组 转换为一个完全二叉堆

*@paramarray 指定的数组

*@paramcomparator 指定的比较器逻辑

**/

public CompleteBinaryHeap(E[] array, Comparatorcomparator){this.innerArrayList = new ArrayList<>(array);this.comparator =comparator;this.size =array.length;//批量建堆

heapify();

}

3.2 辅助方法

由于完全二叉堆在逻辑上等价于一颗完全二叉树,但实际上却采用了一维的向量数据结构来存储元素。因而我们需要实现诸如getParentIndex、getLeftChildIndex、getRightChildIndex等方法来进行完全二叉树和向量表示方法的转换。

这里,定义了一些私有方法来封装常用的逻辑,用以简化代码。

/*** 获得逻辑上 双亲节点下标

*@paramcurrentIndex 当前下标

**/

private int getParentIndex(intcurrentIndex){return (currentIndex - 1)/2;

}/*** 获得逻辑上 左孩子节点下标

*@paramcurrentIndex 当前下标

**/

private int getLeftChildIndex(intcurrentIndex){return (currentIndex * 2) + 1;

}/*** 获得逻辑上 右孩子节点下标

*@paramcurrentIndex 当前下标

**/

private int getRightChildIndex(intcurrentIndex){return (currentInd

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值