# 优先队列（priority queue）的实现（java，jdk接口）

• 底层数据结构，最简单的情况为一维数组；
• 两大接口（以大顶堆为例）：
• push
• 首先将要插入的值置于底层数据结构的末尾：heap[size-1] = value
• 不断地将其与其父节点比较，
• heap[parent] >= heap[pos]，break
• 否则交换 heap[parent] 与 heap[pos] 的值，并将 pos = parent
• pop
• pos = 0
• heap[0] = heap[size-1]
• 将当前值不断地与其左右孩子节点比较：
• leftChild <= rightChild
• 如果 heap[pos] >= heap[rightChild]，break
• 否则
• 交换 heap[pos] 与 heap[rightChild]
• pos = rightChild
• 否则，将 heap[pos] 与 heap[leftChild] 进行比较
• 如果 heap[pos] > = heap[leftChild]，break
• 否则
• 交换 heap[pos]，heap[leftChild]
• pos = leftChild

## 1. java 实现

• 如果当前索引为 pos
• 父节点索引：parent = (pos+1)/2 - 1
• 左孩子：leftChild = pos*2 + 1
• 右孩子：rightChild = pos*2 + 2 或 rightChild = leftChild + 1
package queue;

import java.util.Arrays;

public class PriorityQueue {
private int size;
private int[] heap;

public PriorityQueue(int maxSize) {
heap = new int[maxSize];
size = 0;
}

public void push(int value) {
if (size == heap.length) throw new IllegalStateException();
int pos = size;
heap[pos] = value;
while (pos > 0) {
int parent = (pos+1) / 2 - 1;
if (heap[parent] >= heap[pos]) break;
swapIndices(pos, parent);
pos = parent;
}
++size;
}

public int pop() {
if (size == 0)  throw new IllegalStateException();
int toRet = heap[0];
heap[0] = heap[size-1];
--size;

int pos = 0;
while (pos < size / 2) {
int leftChild = pos * 2 + 1;
int rightChild = pos * 2 + 2;       // leftChild + 1

// 右孩子不一定存在
if (rightChild < size && heap[leftChild] < heap[rightChild]) {
if (heap[pos] >= heap[rightChild]) break;
// heap[pos] < heap[rightChild]
swapIndices(pos, rightChild);
pos = rightChild;
} else {						// 右孩子不存在，或右孩子存在，但右孩子小于左孩子
if (heap[pos] >= heap[leftChild]) break;
swapIndices(pos, leftChild);
pos = leftChild;
}
}
return toRet;

}

private void swapIndices(int i, int j) {
int temp = heap[i];
heap[i] = heap[j];
heap[j] = temp;
}

public void printQueue() {
System.out.println(Arrays.toString(heap));
}

public static void main(String[] args) {
PriorityQueue priorityQueue = new PriorityQueue(10);
priorityQueue.push(0);
priorityQueue.push(1);
priorityQueue.push(2);
priorityQueue.push(3);
priorityQueue.push(4);

priorityQueue.printQueue();

System.out.println(priorityQueue.pop());
System.out.println(priorityQueue.pop());
System.out.println(priorityQueue.pop());
}
}



## 2. jdk api

• 大顶堆与小顶堆

Queue<Integer> minHeap = new PriorityQueue<Integer>();
Queue<Integer> maxHeap = new PriorityQueue<Integer>(Collections.reverseOrder());

• 成员函数：

• add：添加元素
• poll：删除堆顶元素
• peek：查看堆顶元素；

04-14 8万+

11-24 2868

04-23 176

02-17 489

04-19 96

05-29 1274

09-05 217

05-15 1378

11-09 2万+

05-04 3万+

#### Java堆结构PriorityQueue完全解析

©️2020 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

1.余额是钱包充值的虚拟货币，按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载，可以购买VIP、C币套餐、付费专栏及课程。