优先级队列底层是最小堆
基本操作
package bite.hw230110.test;
import bite.hw230104.test.EmptyException;
import java.util.Arrays;
/**
* @Auther: Ying
* @Date: 2023/7/5 - 07 - 05 - 18:35
* @Description: bite.hw230110.test
* @version: 1.0
*/
public class TestHeap {
public int[] elem;
public int usedSize;
public TestHeap(){
elem = new int[10];
}
//这是一个main方法,是程序的入口:
public static void main(String[] args) {
TestHeap heap = new TestHeap();
int[] array = {27,15,19,18,28,34,65,49,25,37};
heap.init(array);
heap.createHeap();
heap.heapSort();
System.out.println("000000000000000000");
}
//这是一个main方法,是程序的入口:
public static void main1(String[] args) {
TestHeap heap = new TestHeap();
int[] arr = {27,15,19,18,28,34,65,49,25,37};
heap.init(arr);
heap.createHeap();
heap.offer(100);
System.out.println(heap.poll());
System.out.println("bjyxszd");
}
public void init(int[] array){
for (int i = 0; i < array.length; i++) {
elem[i] = array[i];
usedSize++;
}
}
/**
* 建堆(大根堆)
* 建堆的时间复杂度:O(N)
*/
public void createHeap(){
for (int parent = (usedSize-1-1)/2;parent>=0;parent--){
shiftDown(parent,usedSize);
}
}
/**
* 向下调整(大根堆)
* 时间复杂度:树的高度
* @param parent
* @param len
*/
private void shiftDown(int parent,int len){
int child = 2*parent+1;
while(child<len){
if((child+1)<len&&elem[child]<elem[child+1]){
child++;
}
if(elem[parent]<elem[child]){
int tmp = elem[child];
elem[child] = elem[parent];
elem[parent] = tmp;
parent = child;
child = parent*2+1;
}else{
break;
}
}
}
// /**
// * 建堆(小根堆)
// * 建堆的时间复杂度:O(N)
// */
// public void createHeap(){
// for (int parent = (usedSize-1-1)/2; parent >= 0; parent--) {
// shiftDown(parent,usedSize);
// }
// }
//
// /**
// * 向下调整(小根堆)
// * 时间复杂度:树的高度
// * @param parent
// * @param len
// */
// private void shiftDown(int parent,int len){
// int child = 2*parent+1;
// while(child<len){
// if((child+1)<len&&elem[child]>elem[child+1]){
// child++;
// }
// if(elem[child]<elem[parent]){
// int tmp = elem[child];
// elem[child] = elem[parent];
// elem[parent] = tmp;
// parent = child;
// child = 2*parent+1;
// }else{
// break;
// }
// }
// }
/**
* 向上调整建堆时间复杂度:O(N*logN)
* @param val
*/
public void offer(int val){
if(isFull()){
elem = Arrays.copyOf(elem,2*elem.length);
}
elem[usedSize] = val;
usedSize++;
//向上调整
shiftUp(usedSize-1);
}
public boolean isFull(){
return usedSize==elem.length;
}
/**
* 向上调整(大根堆)
* 时间复杂度:树的高度
* @param child
*/
private void shiftUp(int child){
int parent = (child-1)/2;
while(child>0||parent>=0){
if(elem[parent]<elem[child]){
int tmp = elem[child];
elem[child] = elem[parent];
elem[parent] = tmp;
child = parent;
parent = (child-1)/2;
}else{
break;
}
}
}
/**
* 堆排序(从小到大)
* 时间复杂度:O(N*logN)
* 空间复杂度:O(1)
*/
public void heapSort(){
int end = usedSize-1;
while (end>0){
swap(elem,0,end);
shiftDown(0,end);
end--;
}
usedSize = end;
}
public void swap(int[] array,int i,int j){
int tmp = array[i];
array[i] = array[j];
array[j] = tmp;
}
public int poll(){
if(isEmpty()){
throw new EmptyException("队列为空异常!");
}
int tmp = elem[0];
elem[0] = elem[usedSize-1];
elem[usedSize-1] = tmp;
usedSize--;
//向下调整
shiftDown(0,usedSize);
return tmp;
}
public boolean isEmpty(){
return usedSize==0;
}
public int peek(){
if(isEmpty()){
throw new EmptyException("队列为空异常!");
}
return elem[0];
}
}
编程应用
最小k个数
class Solution {
public int[] smallestK(int[] arr, int k) {
int[] ret = new int[k];
if(arr==null||k==0){
return ret;
}
Queue<Integer> minHeap = new PriorityQueue<>(arr.length);
for(int i:arr){
minHeap.offer(i);
}
for(int i=0;i<k;i++){
ret[i] = minHeap.poll();
}
return ret;
}
}