优先级队列
优先级队列是一种特殊的队列数据结构,其中每个元素都有一个优先级。与普通队列不同,优先级队列中的元素并不是按入队顺序处理的,而是根据优先级进行处理。
1.优先级队列的模拟实现
优先级队列通常是由堆来实现的,堆实际就是在完全二叉树上做出了调整。
1.堆的概念
把它的所有元素按完全二叉树的顺序存储方式存储在一个一维数组中,满足Ki = K2i+1 且 Ki >= K2i+2) i = 0,1,2...则称为 小堆(或大 堆)。将根节点最大的堆叫做最大堆或大根堆,根节点最小的堆叫做最小堆或小根堆。
小根堆
存储方式
大根堆
存储方式
2.堆的创建
1.堆的向下调整
java
public void siftDown(int parent,int usedSize){
int child=parent*2+1;
while (child<usedSize){
if(child+1<usedSize && elem[child+1]>elem[child]){
child++;
}
if(elem[child]>elem[parent]){
swap(elem,parent,child);
parent=child;
child=parent*2+1;
}else {
break;
}
}
}
private void swap(int[] elem,int parent,int child){
int tem=elem[parent];
elem[parent]=elem[child];
elem[child]=tem;
}
2.堆的创建
java
public void createHeap(){
//第一个减一是因为找最后一个,第二个减一是因为子是父的2倍+1
for (int parent =(this.usedSize-1-1)/2 ; parent>0 ; parent--) {
siftDown(parent,this.usedSize);
}
}
3.堆的向上调整
java
public void siftUp(int child){
int parent=(child-1)/2;
while (parent>=0){
if(elem[child]<elem[parent]){
swap(elem,parent,child);
child=parent;
parent=(child-1)/2;
}else {
break;
}
}
}
private void swap(int[] elem,int parent,int child){
int tem=elem[parent];
elem[parent]=elem[child];
elem[child]=tem;
}
3.堆的插入与删除
1.堆的插入
java
private void offer(int val){
if(isFull()){
return ;
}
elem[usedSize]=val;
siftUp(usedSize);
usedSize++;
}
public boolean isFull(){
return elem.length==usedSize;
}
2.堆的删除
java
public boolean isEmpty(){
return usedSize==0;
}
public int pop(){
if(isEmpty()){
return -1;
}
int val=elem[0];
swap(elem,0,usedSize-1);
siftDown(0,usedSize);
usedSize--;
return val;
}
4.堆的查询和排序
1.堆的查询
java
public int peek(){
if(isEmpty()){
return -1;
}
return elem[0];
}
2.堆的排序
java
private void heapSort(){
int end=usedSize-1;
while (end>0){
swap(elem,0,end);
siftDown(0,end);
end--;
}
}
5.top-k问题:最大或者最小的前k个数据
题目链接:. - 力扣(LeetCode)
方法一:
java
class Solution {
public int[] smallestK(int[] arr, int k) {
PriorityQueue<Integer> priorityQueue=new PriorityQueue<>();
for(int i=0;i<arr.length;i++){
priorityQueue.offer(arr[i]);
}
int[] ret=new int[k];
for(int i=0;i<k;i++){
ret[i]=priorityQueue.poll();
}
return ret;
}
}
方法二:
java
class IntCmp implements Comparator<Integer>{
public int compare(Integer o1,Integer o2){
return o2.compareTo(o1);
}
}
class Solution {
public int[] smallestK(int[] arr, int k) {
int[] ret=new int[k];
if(arr==null || k==0){
return ret;
}
PriorityQueue<Integer> priorityQueue=new PriorityQueue<>(k,new IntCmp());
for(int i=0;i<k;i++){
priorityQueue.offer(arr[i]);
}
for(int i=k;i<arr.length;i++){
int val=priorityQueue.peek();
if(arr[i]<val){
priorityQueue.poll();
priorityQueue.offer(arr[i]);
}
}
for(int i=0;i<k;i++){
ret[i]=priorityQueue.poll();
}
return ret;
}
}
希望能对大家有所帮助!!!!