优先级队列
1.直接new一个PriorityQueue
PriorityQueue底层默认是一个小堆。
代码示例:
public class Test{
public static void main (String[] args) {
Queue<Integer> queue = new PriorityQueue<>();
queue.offer(10);
queue.offer(15);
queue.offer(11);
}
插入完成后,该队列从队头至队尾:10、11、15
2.自己实现一个优先级队列
优先级队列的实现方式有很多,但最常见的是使用堆来构建。
这里以建大堆为例:
入队列
过程:
- 首先按尾插方式放入数组
- 比较其和其双亲的值的大小,如果双亲的值大,则满足堆的性质,插入结束
- 否则,交换其和双亲位置的值,重新进行 2、3 步骤
- 直到根结点
出队列(优先级最高的出队列)
为了防止破坏堆的结构,删除时并不是直接将堆顶元素删除,而是用数组的最后一个元素替换堆顶元素,然后通过向下调整方式重新调整成堆
返回队首元素
返回堆顶的元素,但不删除。
优先级队列代码示例:
public class TestHeap {
public int[] elem;
public int usedSize;
public TestHeap() {
this.elem = new int[20];
this.usedSize = usedSize;
}
//首先,建堆
public void createHeap(int[] array) {
for(int i = 0;i < array.length;i++){
elem[i] = array[i];
this.usedSize++;
}
//从最后一棵子树开始向下调整,
for(int i = (this.usedSize - 1 -1 )/2;i >= 0;i--){
adjustDown(i,this.usedSize);
}
}
//向下调整
public void adjustDown(int root,int len) {
int parent = root;
int child = 2 * parent + 1;
while(child < this.usedSize) {
if(child + 1 < this.usedSize && elem[child] < elem[child + 1]) {
child = child + 1;
}
if(elem[child] > elem[parent]) {
int tmp = elem[child];
elem[child] = elem[parent];
elem[parent] = tmp;
parent = child;
child = 2 * parent + 1;
} else {
break;
}
}
}
public boolean isFull(){
if(this.usedSize == elem.length){
return true;
}
return false;
}
//入队:放到数组的最后一个下标,之后向上调整
public void pushHeap(int val){
if(isFull()){
this.elem = Arrays.copyOf(this.elem,this.elem.length*2);
}
elem[usedSize] = val;
this.usedSize++;
adjustUp(this.usedSize-1);
}
//向上调整
public void adjustUp(int child){
int parent = (child-1)/2;
while( child > 0){
if(elem[child] > elem[parent]){
int tmp = elem[child];
elem[child] = elem[parent];
elem[parent] = tmp;
child = parent;
parent = (child-1)/2;
}else{
break;
}
}
}
//出队,对头元素出队
public void popHeap(){
//0.如果堆为空
//1.根顶元素和最后一个元素进行交换
//2.向下调整,只需调整0号下标这棵树
if(this.usedSize == 0){
return;
}
int tmp = elem[0];
elem[0] = elem[this.usedSize-1];
this.usedSize--;
adjustDown(0,this.usedSize);
}
//得到堆顶元素
public int getPop(){
if(this.usedSize == 0){
return -1;
}
return this.elem[0];
}
public void display(){
for(int i = 0;i < this.usedSize;i++){
System.out.print(elem[i] + " ");
}
System.out.println();
}
//堆排序
public void heapSort() {
//end为每次调整的结束位置
int end = this.usedSize-1;
while(end > 0){
int tmp = this.elem[0];
this.elem[0] = this.elem[end];
this.elem[end] = tmp;
adjustDown(0,end);
end--;
}
}
}
//