Java:数据结构-优先级队列(堆)

优先级队列

优先级队列是一种特殊的队列数据结构,其中每个元素都有一个优先级。与普通队列不同,优先级队列中的元素并不是按入队顺序处理的,而是根据优先级进行处理。

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;
    }
}

希望能对大家有所帮助!!!!

相关推荐
刘马想放假11 小时前
Modbus 全栈技术解析:TCP、RTU、ASCII、RTU over TCP
数据结构·网络协议
北域码匠1 天前
冒泡排序太慢?鸡尾酒排序双向优化,原生 C# 零第三方库完整代码
数据结构·排序算法·泛型·c# 算法·鸡尾酒排序·原生 c# 开发·冒泡排序优化·嵌入式算法
Darling噜啦啦8 天前
列表转树算法深度解析:从 Map 到 Reduce 的两种实现,面试高频考点
数据结构·算法·面试
小小工匠9 天前
Redis - 事务机制:能实现 ACID 属性吗
数据结构·redis·性能优化·并发·持久化
玖玥拾9 天前
C/C++ 数据结构(七)栈、容器适配器
c语言·数据结构·c++··容器适配器
Qres8219 天前
算法复键——树状数组
数据结构·算法
牛油果子哥q9 天前
并查集(DSU)超精讲,路径压缩、按秩合并、万能模板、连通性判定、最小生成树与刷题实战全解
数据结构·c++·最小生成树·并查集
凌波粒9 天前
LeetCode--491.递增子序列(回溯算法)
数据结构·算法·leetcode
WL学习笔记9 天前
单项不带头不循环链表
数据结构·链表
小糯米60110 天前
JS 数组
数据结构·算法·排序算法