package cn.tan.heap;
import java.lang.reflect.Array;
import java.util.Arrays;
//优先队列默认小堆
public class MyPriorityQueue {
private long[] arr;
private int size;
public int size(){
return size;
}
public boolean isEmpty(){
return size==0;
}
public MyPriorityQueue(){
arr=new long[16];
size=0;
}
//offer用向上调整,因为插入用的是尾插,所以需要对新插入的元素进行调整
public void offer(long e){
ensureCapacity();
arr[size]=e;
size++;
shiftup(arr,size-1);
}
// 前提:size > 0
public long peek() {
// 返回堆顶元素
if (size < 0) {
throw new RuntimeException("队列是空的");
}
return arr[0];
}
//删除并返回堆顶元素
public long poll(){
if(size<0){
throw new RuntimeException("队列是空的");
}
long e=arr[0];
arr[0]=arr[size-1];
arr[size-1]=0;
size--;
shiftDown(arr,size,0);
return e;
}
private void shiftDown(long[] arr, int size, int index) {
while (2*index+1<size){
int min=index*2+1;
int right=min+1;
if(right<size&&arr[right]<arr[min]){
min=right;
}
if(arr[index]<=arr[min]){
return;
}
swap(arr,min,index);
index=min;
}
}
private void shiftup(long[] arr, int index) {
while(index!=0){
int parent=(index-1)/2;
if(arr[parent]<=arr[index]){
return;
}
swap(arr,parent,index);
index=parent;
}
}
public void check(){
if(size<0||size>arr.length){
throw new RuntimeException("size 约束错误");
}
for(int i=0;i<size;i++){
int left=2*i+1;
int right=left+1;
if(left>=size){
continue;
}
if(arr[i]>arr[left]){
throw new RuntimeException(String.format("[%d]位置的值大于其左孩子的值了",i));
}
if(right<size&&arr[i]>arr[right]){
throw new RuntimeException(String.format("[%d]位置的值大于其右孩子的值了",i));
}
}
}
private void swap(long[] array, int i, int j) {
long t= array[i];
array[i] = array[j];
array[j] = t;
}
private void ensureCapacity() {
if(size<arr.length){
return;
}
arr= Arrays.copyOf(arr,arr.length*2);
}
}
-
很重要的属性:堆 = 数组 + 有效元素个数
-
优先队列三个重要操作,offer(),poll(),peek();
package cn.tan.heap; public class Test { public static void main(String[] args) { MyPriorityQueue pq=new MyPriorityQueue(); pq.check(); pq.offer(3); pq.check(); pq.offer(7); pq.check(); pq.offer(1); pq.check(); pq.offer(2); pq.check(); pq.offer(5); pq.check(); pq.offer(0); long peek=pq.peek(); System.out.println(peek); System.out.println("======="); while(!pq.isEmpty()){ long poll=pq.poll(); pq.check(); System.out.println(poll); } } }