优先级队列(堆)

1.1背景:

队列是一种先进先出(FIFO)的数据结构,但有些情况下,操作的数据可能带有优先级,例如,出队列时,可能需要优先级高的元素先出队列,(中学时班主任排座位时可能会让成绩好的同学先挑座位)。

在这种情况下就需要使用到优先级队列(Priority Queue)。

1.2堆的概念:

如果有一个关键码的集合K = {k0k1k2kn-1},把它的所有元素按完全二叉树的顺序存储方式存储 在一个一维数组中,并满足:Ki <= K2i+1 Ki<= K2i+2 (Ki >= K2i+1 Ki >= K2i+2) i = 012…,则称为 小堆(或大)。将根节点最大的堆叫做最大堆或大根堆,根节点最小的堆叫做最小堆或小根堆。

1.3堆的性质:

1)堆中某个节点的值总是不大于或不小于其父节点的值;

 2)堆总是一棵完全二叉树。

2优先级队列的模拟实现

2.1堆的创建(向下调整)

向下过程(以小堆为例)

  1. parent标记需要调整的节点,child标记parent的左孩子(注意:parent如果有孩子一定先是有左孩子)。
  2. 如果parent的左孩子存在,即:child   <   size, 进行以下操作,直到parent的左孩子不存在。

判断parent右孩子是否存在,存在找到左右孩子中最小的孩子,让child进行标 parent与较小的孩子child比较,如果:

parent小于较小的孩子child,调整结束。

public void shiftDown(int[] array, int parent) {
// child先标记parent的左孩子,因为parent可能右左没有右
int child = 2 * parent + 1;
int size = array.length; 
while (child < size) {
//    如果右孩子存在,找到左右孩子中较小的孩子,用child进行标记
if(child+1 < size && array[child+1] < array[child]){
child += 1;
}

// 如果双亲比其最小的孩子还小,说明该结构已经满足堆的特性了
if (array[parent] <= array[child]) {
 break;
}else{
// 将双亲与较小的孩子交换
int t = array[parent]; 
array[parent] = array[child]; 
array[child] = t;

// parent中大的元素往下移动,可能会造成子树不满足堆的性质,因此需要继续向下调整parent = child;
child = parent * 2 + 1;
}
}
}

否则:交换parent与较小的孩子child,交换完成之后,parent中大的元素向下移动,可能导致子树不满足对的性质,因此需要继续向下调整,即parent = childchild = parent*2+1; 然后继续2

插入/删除/获取优先级最高的元素

函数名

功能介绍

boolean offer(E e)

插入元素e,插入成功返回true,如果e对象为空,抛出NullPointerException异常,时间复杂 ,注意:空间不够时候会进行扩容

E peek()

获取优先级最高的元素,如果优先级队列为空,返回null

E poll()

移除优先级最高的元素并返回,如果优先级队列为空,返回null

int size()

获取有效元素的个数

void clear()

清空

boolean isEmpty()

检测优先级队列是否为空,空返回true

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值