优先级队列
1、概念
优先级队列应当提供两个操作:
(1)返回最高优先级对象;
(2)添加新的对象
2、内部原理
实现优先级队列的方式很多,但最常见的是用堆来构建
3、操作 - 入队列
过程(以大堆为例)
(1)首先按尾插方式放入数组
(2)比较其和其双亲的值的大小,如果双亲的值大,则满足堆的性质,插入结束
(3)否则,交换其和双亲位置的值,重新进行 (2)(3)步骤
(4)直到根结点
4、操作 - 出队列(优先级最高)
为了防止破坏堆的结构,删除时并不是直接将堆顶元素删除,而是用数组的最后一个元素替换堆顶元素,然后通过向下调整方式重新调整成堆
5、返回队首元素(优先级最高)
返回堆顶元素即可
6、代码实现
public class MyPriorityQueue {
private int[] array = new int[100];
private int size = 0;
//向上调整,建一个大堆
private static void shiftUp(int[] array,int index){
int child = index;
//根据孩子结点,找到双亲节点
int parent = (child - 1)/2;
while(child > 0){
//若孩子结点大于双亲节点,就交换两个结点的值
if(array[child] >array[parent]){
int temp = array[child];
array[child] = array[parent];
array[parent] = temp;
}
//更新结点
child = parent;
parent = (child -1)/2;
}
}
//向下调整,建一个大堆
private static void shiftDown(int[] array,int size,int index){
int parent = index;
//根据双亲节点,找到孩子结点
int child = parent * 2 + 1;
while(child<size){
//找到孩子结点中比较大的一个
if( child+1 < size && array[child+1]>array[child]){
child++;
}
//若孩子结点大于双亲节点,就交换两个结点的值
if(array[child] >array[parent]){
int temp = array[child];
array[child] = array[parent];
array[parent] = temp;
}
//更新结点
parent = child;
child = parent * 2 + 1;
}
}
//入队
public void offer(int x){
array[size] = x;
size ++;
shiftUp(array,size-1);
}
//出队
public int poll(){
int pollValue = array[0];
array[0] = array[size -1];
size --;
shiftDown(array,size,0);
return pollValue;
}
//取队首元素
public int peek(){
return array[0];
}
//判断队是否为空
public boolean isEmpty(){
return size == 0;
}
}
7、java中的优先级队列
代码演示:
import java.util.PriorityQueue;
public class TestPriorityQueue {
public static void main(String[] args) {
//创建一个优先级队列
PriorityQueue<Integer> queue = new PriorityQueue<>();
//入队
queue.offer(9);
queue.offer(5);
queue.offer(2);
queue.offer(7);
queue.offer(3);
queue.offer(6);
queue.offer(8);
//出队、取队首元素、判断队是否为空
/*
在这里,每出队一次,取一次队首元素、判断一次队是否为空;
直到队为空
*/
System.out.print("出队:");
while(!queue.isEmpty()){
System.out.println();
int cur = queue.poll();
System.out.print(cur);
System.out.println();
System.out.print("取队首元素:");
System.out.print(queue.peek());
System.out.println();
System.out.print("判断队是否为空:");
System.out.print(queue.isEmpty());
System.out.println("\n");
}
}
}