文章目录
概要
优先级队列实际是小堆,根据不同的比较方法实现小堆,也可以根据自己的需要重写比较方法,从而实现自己想要的优先级队列,获取想要的数据,接下来将会用整数模拟实现一个优先级队列;
这里我的优先是优先获取最小的元素,保证出队的永远是现存的数据里最小的;
整体架构流程
package dom.bite;
import java.util.Arrays;
public class PriorityQueue {
public int[] elem;
public int usedSize;
//这里会优先插入一些元素,
public PriorityQueue(int[] arr,int usedSize) {
this.usedSize=usedSize;
this.elem=new int[usedSize];
for (int i = 0; i < usedSize; i++) {
this.elem[i]=arr[i];
}
createHeap(arr);
}
}
- 将数据整理成小根堆,采用向下调整的方法
- http://t.csdnimg.cn/1nP5F
public void createHeap(int[] array) {
int parent=(array.length-1-1)/2;
while(parent>=0){
shiftDown(parent,array.length-1);
parent--;
}
}
/**
*
* @param root 是每棵子树的根节点的下标
* @param len 是每棵子树调整结束的结束条件
* 向下调整的时间复杂度:O(logn)
*/
private void shiftDown(int root,int len) {
int parent=root;
int end=len;
int child=parent*2+1;
while(child<=end){
if (child + 1 <= end && elem[child+1] > elem[child]){
child++;
}
if(elem[child]>elem[parent]){
swap(child,parent);
parent=child;
child=parent*2+1;
}else{
break;
}
}
}
再者接口就是入队元素
入队采用尾插,然后采用向上调整的方法
private void shiftUp(int child) {
int parent=(child-1)/2;
int end=child;
child=parent*2+1;
while(parent>=0){
if (child + 1 <= end && elem[child + 1]<elem[child]) {
child++;
}
if(elem[child]<elem[parent]){
swap(child,parent);
child=parent;
parent=(child-1)/2;
}else{
break;
}
}
}
再者就是出队元素,优先队列出的就是最小的或者最大的看自己的选择
而后保证该队列还是小根堆或者大根堆
public void pollHeap() {
if(!isEmpty()){ //不为空就进行出队操作
swap(0,usedSize-1); //交换第一个元素和最后一个元素,出队最后一个元素,
变相出队根地元素
usedSize--; //插入的元素的元素个数减一
shiftDown(0,usedSize-1); //交换上去的元素,即放在的元素向下调整
}
}
获取堆顶元素
public int peekHeap() {
return elem[0];
}
其他操作方法
//判断队列是否满了
public boolean isFull() {
return usedSize==elem.length;
}
//判断队列是否为空
public boolean isEmpty() {
return usedSize==0;
}
//交换元素
public void swap(int swap1,int swap2){
int tmp=elem[swap1];
elem[swap1]=elem[swap2];
elem[swap2]=tmp;
}
//满了,扩容
public void grow(){
int newCapacity=elem.length+10;
elem=Arrays.copyOf(elem,newCapacity);
}
小结
堆的应用
4.1 PriorityQueue的实现
用堆作为底层结构封装优先级队列
4.2 堆排序 堆排序即利用堆的思想来进行排序,总共分为两个步骤:
1. 建堆 升序:建大堆 降序:建小堆
2. 利用堆删除思想来进行排序 建堆和堆删除中都用到了向下调整,因此掌握了向下调整,就可以完成堆排序。
使用小根堆实现Java优先级队列及堆排序算法详解
本文介绍了如何使用整数模拟实现一个优先级队列,通过小根堆结构确保出队总是最小元素。同时讲述了堆排序的过程,包括建堆、堆调整和堆排序的基本步骤。适用于技术面试准备,如LeetCode中的相关题目。
https://leetcode.cn/problems/smallest-k-lcci/description/
1098

被折叠的 条评论
为什么被折叠?



