## 什么是优先队列

O(logn) O(logn)
interface Queue<E> {

int getSize();
boolean isEmpty();
void enqueue(E element);
E dequeue();
E getFront();
}

class PriorityQueue<E extends Comparable<E>> implements Queue<E>{

private MaxHeap<E> maxHeap;

public PriorityQueue(){

maxHeap = new MaxHeap();
}

@Override
public int getSize(){

return maxHeap.size();
}

@Override
public boolean isEmpty(){

return maxHeap.isEmpty();
}

@Override
public E getFront(){

return maxHeap.findMax();
}

@Override
public void enqueue(E element){

}

@Override
public E dequeue(){

return maxHeap.extractMax();
}
}

class MaxHeap<E extends Comparable<E>>{

private Array<E> heap;

public MaxHeap(int capacity){

heap = new Array<>(capacity);
}

public MaxHeap(){

heap = new Array<>(10);
}

public MaxHeap(E[] arr){

heap = new Array<>(arr);
heapify(arr);
}

public int size(){

return heap.getSize();
}

public boolean isEmpty(){

return heap.getSize() == 0;
}

public int parent(int index){

if (index == 0) {
throw new IllegalArgumentException("根节点没有父节点");
}
return (index - 1) / 2;
}

private int leftChild(int index){

return 2 * index + 1;
}

private int rightChild(int index){

return 2 * index + 2;
}

siftUp(size() - 1);
}

private void siftUp(int index){

while (index > 0 && heap.get(index).compareTo(heap.get(parent(index))) > 0){

heap.swap(index, parent(index));
index = parent(index);
}
}

public E findMax(){

if (size() == 0){
throw new IllegalArgumentException("堆为空");
}

return heap.get(0);
}

public E extractMax(){

E max = findMax();

heap.swap(0, size() - 1);
heap.remove(size() - 1);
siftDown(0);

return max;
}

public void siftDown(int index){

while (leftChild(index) < size()){

int max = leftChild(index);

if (rightChild(index) < size() && heap.get(leftChild(index)).compareTo(heap.get(rightChild(index))) < 0){
max = rightChild(index);
}

if (heap.get(index).compareTo(heap.get(max)) >= 0){
break;
}

heap.swap(index, max);
index = max;
}
}

public void heapify(E[] arr){

if (arr.length > 1){
for (int i = parent(arr.length - 1); i >= 0; i--) {
siftDown(i);
}
}
}

public E replace(E e){

E max = findMax();
heap.set(e, 0);
siftDown(0);

return max;
}
}

class Array<E>{

private E[] data;
private int size;

public Array(int capacity){

data = (E[]) new Object[capacity];
size = 0;
}

public Array(E[] arr){

data = (E[]) new Object[arr.length];

for (int i = 0; i < arr.length; i++) {
data[i] = arr[i];
}

size = arr.length;
}

public Array(){

data = (E[]) new Object[10];
size = 0;
}

public int getSize(){

return size;
}

public void swap(int index1, int index2){

E temp;
temp = data[index1];
data[index1] = data[index2];
data[index2] = temp;
}

public E get(int index){

if (index < 0 || index >= size){
throw new IllegalArgumentException("索引值非法");
}

return data[index];
}

public void set(E e, int index){

if (index < 0 || index >= size){
throw new IllegalArgumentException("索引值非法");
}

data[index] = e;
}

public void add(E e, int index){

if (index < 0 || index > size){
throw new IllegalArgumentException("索引值非法");
}

if (size == data.length){
resize(2 * data.length);
}

for (int i = index - 1; i >= index; i++) {
data[i + 1] = data[i];
}

data[index] = e;
size++;
}

}

public void remove(int index){

if (index < 0 || index >= size){
throw new IllegalArgumentException("索引值非法");
}

for (int i = index + 1; i < size; i++) {
data[i - 1] = data[i];
}

size--;
data[size] = null;

if (size == data.length / 2 && data.length / 2 != 0){
resize(data.length / 2);
}
}

public void resize(int newCapacity){

E[] temp = (E[])new Object[newCapacity];

for (int i = 0; i < size; i++) {
temp[i] = data[i];
}

data = temp;
}

@Override
public String toString(){

StringBuilder str = new StringBuilder();
str.append("[");

for (int i = 0; i < size; i++) {

str.append(data[i]);

if (i != size - 1){
str.append(", ");
}
}

str.append("]");

return str.toString();
}
}