PriorityQueue优先级队列

前言

优先级队列就是在堆的基础上进行改造,那么什么是堆,又什么是优先级队列呢?

我们一起来看看吧!

 


目录

前言

一、堆

(一)堆的创建

(二)堆的插入

(三)堆的删除

(四)模拟实现堆

二、优先级队列

(一)常用方法:

(二)常考点

结语


一、堆

堆就是堆中某个节点的值总是不大于或不小于其父节点的值。

堆总是完全二叉树。

Java底层的堆是顺序表,按照层序遍历的规则存储数据。

堆分为小根堆和大根堆。

1.小根堆(又名最小堆)

就是堆中某个节点的值总是不小于其父节点的值。

例如:

 

2.大根堆(又名最大堆)

就是堆中某个节点的值总是不大于其父节点的值。

 例如:

 

以创建最小堆为例,给出的数据顺序是: 5、3、6、7、4、2.

(一)堆的创建

首先,根据给出的数据顺序,创建如下二叉树:

 从最后一个叶子节点开始调整(向上调整):

时间复杂度是:O(n)

(二)堆的插入

假设要插入数据0:

如果在插入数据时,堆满扩容;调整为向上调整。 

时间复杂度是:O(log n)

(三)堆的删除

堆的删除一定删除的是堆顶元素。

时间复杂度是:O(log n) 

(四)模拟实现堆

代码:

import java.util.Arrays;
import java.util.Comparator;

class PriorityException extends RuntimeException{
    public PriorityException(String s){
        super(s);
    }
}


public class MyPriortyQueue implements Comparator<Integer> {
    public int[] elem;
    public int usedSize;

    public MyPriortyQueue(int k) {
        elem = new int[k];
    }

    public MyPriortyQueue() {
        elem = new int[11];
    }

    @Override
    public int compare(Integer o1,Integer o2) {
        return o2.compareTo(o1);
    }

    /**
     * 建堆
     */
    public void createHeap(int[] array) {
        for(int i = 0; i < array.length; i++){
            elem[i] = array[i];
            usedSize++;
        }
        for(int i = (usedSize-1-1)/2; i >= 0; i--){
            shiftDown(i,usedSize-1);
        }
    }

    /**
     * 向下调整
     * @param root 是每棵子树的根节点的下标
     * @param len  是每棵子树调整结束的结束条件
     * 向下调整的时间复杂度:O(logn)
     */
    private void shiftDown(int root,int len) {
        int child = root*2+1;
        while(child < len){
            if(child+1<len && compare(elem[child],elem[child+1])>0){
                child++;
            }
            if(compare(elem[root],elem[child])>0){
                int tmp = elem[root];
                elem[root] = elem[child];
                elem[child] = tmp;
                root = child;
                child = root*2+1;
            }else{
                break;
            }
        }
    }


    /**
     * 入队:仍然要保持是大根堆
     * @param val
     */
    public void push(int val) {
        if(isEmpty()){
            elem[0] = val;
        }else{
            elem[usedSize] = val;
        }
        usedSize++;
        shiftUp(usedSize-1);
    }
    /**
     * 向上调整
     * 默认除了需要调整的地方外,其余都是已经调整好了的
     */
    private void shiftUp(int child) {
        int parent = (child-1)/2;
        while(child > 0){
            if(compare(elem[parent],elem[child])>0){
                int tmp = elem[parent];
                elem[parent] = elem[child];
                elem[child] = tmp;
                child = parent;
                parent = (child-1)/2;
            }else{
                break;
            }
        }
    }

    public boolean isFull() {
        return usedSize == elem.length;
    }

    /**
     * 出队【删除】:每次删除的都是优先级高的元素
     * 仍然要保持是大根堆
     */
    public void pollHeap() throws PriorityException{
        if(isEmpty()){
            throw new PriorityException("pollHeap::队列无元素,删除失败");
        }
        elem[0] = elem[usedSize-1];
        usedSize--;
        shiftDown(0, usedSize-1);
    }

    public boolean isEmpty() {
        return usedSize == 0;
    }

    /**
     * 获取堆顶元素
     * @return
     */
    public int peekHeap() throws PriorityException{
        if(isEmpty()){
            throw new PriorityException("peekEmpty::队列无元素,获取失败");
        }
        return elem[0];
    }

    public static void main(String[] args) {
        MyPriortyQueue p = new MyPriortyQueue();
        int[] arr = {2,4,2,5,7,9,5,3};
        p.createHeap(arr);
        System.out.println("+=========创建一个堆========+");
        System.out.println(Arrays.toString(p.elem));
        p.push(10);
        System.out.println("+=========入一个值========+");
        System.out.println(Arrays.toString(p.elem));
        System.out.println("+=========输出堆顶========+");
        System.out.println(p.peekHeap());
        p.pollHeap();
        System.out.println("+=========删除堆顶=======+");
        System.out.println(Arrays.toString(p.elem));
    }
}

代码链接在GitHub:堆_练习模拟实现2 · Yjun6/DataStructrue@98faae5 (github.com)

二、优先级队列

PriorityQueue<Integer> p = new PriorityQueue<>();

(一)常用方法:

boolean offer(E e)插入元素e,成功插入返回true;会自动扩容;如果e为空,会抛出异常
E peek()获取优先级队列最高的元素;若队列为空,返回null
E poll()移除优先级队列最高的元素;若队列为空,返回null
int size()获取有效元素个数
void clear()清空
boolean isEmpty()判断是否为空

关于创建优先级队列的方法:

PriorityQueue()初始容量为11,默认无比较器
PriorityQueue(int k)初始容量为k,k>0
PriorityQueue(Collection<? extend E> c)用一个集合创建优先级队列

优先级队列扩容说明:

  • 如果容量小于64,按照2倍扩容;
  • 如果容量大于等于64,按照1.5倍扩容;
  • 如果容量超过 MAX_ARRAY_SIZE,按照 MAX_ARRAY_SIZE 进行扩容。

(二)常考点

求前k个最大值、前k个最小值、第k个最大值、第k个最小值……

面试题 17.14. 最小K个数 - 力扣(Leetcode)

代码:

class Solution {
    public int[] smallestK(int[] arr, int k) {
        if(arr == null || k == 0) return new int[k];
        Comp comp = new Comp();
        PriorityQueue<Integer> priorityQueue = new PriorityQueue<>(comp);//求大根堆
        for(int i = 0; i < k; i++){
            priorityQueue.offer(arr[i]);
        }
        for(int i = k; i < arr.length; i++){
            if(arr[i] < priorityQueue.peek()){
                priorityQueue.poll();
                priorityQueue.offer(arr[i]);
            }
        }
        int[] str = new int[priorityQueue.size()];
        for(int i = 0; i < str.length; i++){
            str[i] = priorityQueue.poll();
        }
        return str;
    }
}


class Comp implements Comparator<Integer> {
    @Override
    public int compare(Integer a, Integer b){
        return b.compareTo(a);
    }
}

结语

小编能力有限,欢迎大家指出错误哦~

这篇博客如果对你有帮助,给博主一个免费的点赞以示鼓励,欢迎各位🔎点赞👍评论收藏⭐,谢谢!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/24682.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

群晖DS920 video station使用教程

群晖DS920 video station使用教程 为了更好的浏览体验&#xff0c;欢迎光顾勤奋的凯尔森同学个人博客http://www.huerpu.cc:7000 安装video station在群晖套件里点一下就好&#xff0c;这里不说了。 一、添加视频库 可以添加电视剧、电视节目等类型。 比如我在国产剧这个视频…

uniapp滚动加载 下拉刷新

前言 在日常开发中&#xff0c;滚动加载和下拉刷新是非常常见的功能&#xff0c;页面数据过多时&#xff0c;需要滚动加载优化性能&#xff0c;本篇技术分享博客将介绍如何在uniapp中实现滚动加载和下拉刷新。 预览 滚动加载 下拉刷新 一、滚动加载 滚动加载指的是当用户滑…

PHP 反序列化漏洞

PHP反序列化漏洞在实际测试中出现的频率并不高&#xff0c;主要常出现在CTF中。 PHP序列化概述 PHP序列化函数&#xff1a; serialize&#xff1a;将PHP的数据&#xff0c;数组&#xff0c;对象等序列化为字符串unserialize&#xff1a;将序列化后的字符串反序列化为数据&…

java 利用poi根据excel模板导出数据(二)

本文是 java 利用poi根据excel模板导出数据&#xff08;一&#xff09; 的续篇 经常有poi的开发一定会碰到三个名词&#xff1a; HSSFWorkbook 、 XSSFWorkbook、SXSSFWorkbook&#xff1b; 这三个都是导出excel的形式&#xff0c;具体区别&#xff1a; HSSFworkbook,XSSF…

Golang每日一练(leetDay0080) 矩形面积、翻转二叉树

目录 223. 矩形面积 Rectangle Area &#x1f31f;&#x1f31f; 226. 翻转二叉树 Invert Binary Tree &#x1f31f; &#x1f31f; 每日一练刷题专栏 &#x1f31f; Rust每日一练 专栏 Golang每日一练 专栏 Python每日一练 专栏 C/C每日一练 专栏 Java每日一练 专栏…

SAP-MM-采购申请-价值特性

采购申请审批在维护价值特性时要注意是抬头价值还是行价值&#xff0c;要确定选择哪个&#xff0c;配置时对应配置。 1、创建价值特性CT04 字段名称&#xff1a;CEBAN-GSWRT&#xff0c;和CEBAN-GFWRT 抬头总价值&#xff1a;CEBAN-GFWRT&#xff1b;如果选择的是抬头审批&am…

数字信号处理8:利用Python进行数字信号处理基础

我前两天买了本MATLAB信号处理&#xff0c;但是很无语&#xff0c;感觉自己对MATLAB的语法很陌生&#xff0c;看了半天也觉得自己写不出来&#xff0c;所以就对着MATLAB自己去写用Python进行的数字信号处理基础&#xff0c;我写了两天左右&#xff0c;基本上把matlab书上的代码…

开源云原生数仓引擎ByConity 存储计算分离架构和优势

供稿 | ByConity技术团队 出品 | CSDN 云计算 ByConity是一款字节跳动开源的云原生数仓引擎。它的一个重要优势是采用存储计算分离的架构&#xff0c;实现了读写分离和弹性扩缩容。这种架构确保读操作和写操作不会相互影响&#xff0c;使得计算资源和存储资源解耦&#xff0c;…

基于html+css的图展示102

准备项目 项目开发工具 Visual Studio Code 1.44.2 版本: 1.44.2 提交: ff915844119ce9485abfe8aa9076ec76b5300ddd 日期: 2020-04-16T16:36:23.138Z Electron: 7.1.11 Chrome: 78.0.3904.130 Node.js: 12.8.1 V8: 7.8.279.23-electron.0 OS: Windows_NT x64 10.0.19044 项目…

BLE协议栈结构

// 开坑BLE协议栈 0 镇楼图 接下来会自下往上粗略分析各个层级&#xff0c;后续会有对各层的细致解读 1 CONTROLLER 1.1 PHY BLE使用ISM频段&#xff08;频率范围是2.400-2.4835 GHz&#xff09;。将整个频带分为40份&#xff0c;每份的带宽为2MHz&#xff0c;称作RF Chann…

如何使用Python自动化测试工具Selenium进行网页自动化?

引言 Selenium是一个流行的Web自动化测试框架&#xff0c;它支持多种编程语言和浏览器&#xff0c;并提供了丰富的API和工具来模拟用户在浏览器中的行为。Selenium可以通过代码驱动浏览器自动化测试流程&#xff0c;包括页面导航、元素查找、数据填充、点击操作等。 与PyAuto…

抖音账号矩阵系统源码开发之——视频发布功能开发

视频发布权限在账号矩阵系统研发之初&#xff0c;都是一个备受争议的功能&#xff0c;最早之前我们使用的视频发布权限名字是Video.creat, video.delete权限&#xff0c;但是该权限于2022年10月份做了权限的收回&#xff0c;后又在上架了一个能力叫发布内容至抖音&#xff1a;…

PostGIS的10个最佳实践

PostGIS 是一个功能强大的开源空间数据库&#xff0c;可用于存储、查询和分析地理空间数据。 对于需要存储和分析大量地理空间数据的组织来说&#xff0c;这是一个流行的选择。 但是&#xff0c;正确使用 PostGIS 以充分利用它很重要。 在本文中&#xff0c;我们将讨论 10 个 …

【2023年4月美赛加赛】Z题:The future of Olympics 25页完整论文

【2023年4月美赛加赛】Z题&#xff1a;The future of Olympics 25页完整论文 1 题目 背景 国际奥委会(IOC)正面临着夏季奥运会和冬季奥运会申办数量的减少**[1]**。在过去&#xff0c;举办奥运会的竞争非常激烈&#xff0c;声望也很高。然而&#xff0c;最近&#xff0c;主办…

自定义注解和@Target、@Retention注解的使用

说明&#xff1a;注解可以理解为另一种形式的配置&#xff0c;可用于在类上、方法上等&#xff0c;标志是“”&#xff0c;如重写方法上的“Override”就是一种注解。这里我通过一个实例&#xff0c;来介绍自定义注解和java元注解&#xff08;Target、Retention&#xff09;的使…

一分钟了解乐观锁、悲观锁、共享锁、排它锁、行锁、表锁以及使用场景

大家好&#xff0c;我是冰点&#xff0c;今天给大家带来&#xff0c;关于MySQL中的锁的使用。 我首先提个问题&#xff0c;大家知道什么是 乐观锁、悲观锁、共享锁&#xff0c;、排它锁、行锁、表锁&#xff0c;以及每种锁的使用场景吗&#xff1f; !! 背景&#xff1a;最近在各…

(学习日记)2023.04.23

写在前面&#xff1a; 由于时间的不足与学习的碎片化&#xff0c;写博客变得有些奢侈。 但是对于记录学习&#xff08;忘了以后能快速复习&#xff09;的渴望一天天变得强烈。 既然如此 不如以天为单位&#xff0c;以时间为顺序&#xff0c;仅仅将博客当做一个知识学习的目录&a…

关于安卓以及微软用户chatgpt上一篇文章如今第五点无法正常进入更新解决方法以及附加本地部署

目录 一、问题出现&#xff1a; 1、问题&#xff1a; 原因&#xff1a; 二、解决办法&#xff08;本地部署chatgpt&#xff09; 1、解决&#xff08;国内网络使用真的chatgpt并非镜像&#xff09;一次部署终生使用 第一步&#xff1a; ​编辑第二步&#xff1a; 三、实现结…

让你不再好奇怎么给小说配音

你是否曾经想象过&#xff0c;当你在读小说时&#xff0c;你可以听到人物的声音&#xff0c;感受到情感和气氛的变化&#xff1f;有声书的出现已经让这一切成为可能。然而&#xff0c;如何为小说创造生动的配音效果却是一个需要仔细考虑的问题。如果你还不知道怎么给小说配音的…

智能计价器-第14届蓝桥杯省赛Scratch中级组真题第5题

[导读]&#xff1a;超平老师的《Scratch蓝桥杯真题解析100讲》已经全部完成&#xff0c;后续会不定期解读蓝桥杯真题&#xff0c;这是Scratch蓝桥杯真题解析第140讲。 智能计价器&#xff0c;本题是2023年5月7日举行的第14届蓝桥杯省赛Scratch图形化编程中级组真题第5题&#…