优先级队列(堆)的详解

2023/11/30 9:15:12

      优先级队列提供了两个最基本的操作:一个是返回最高优先级对象,一个是添加新的对象,优先级队列底层实现用到的数据结构就是堆

一、堆 

1、堆的概念

        如果有一个关键码的集合的所有元素按照完全二叉树的顺序存储方式存储在一个一维数组中,并满足ki <= k2i + 1且ki <= k2i + 2  (ki >= k2i + 1且ki >= k2i + 2  ),则称为小堆(或大堆)。根节点最大的堆为大根堆或者最大堆,根节点最小的堆为小根堆或最小堆

2、堆的存储方式

        堆是一颗完全二叉树,因此可以层序的规则采用顺序的方式来高效存储

3、堆的创建

         由于根节点的左右子树已经完全满足堆的性质,因此只需要将根节点向下调整好即可

private void createSort(int[] arr) {
        for (int parent = (arr.length - 2) / 2;parent >= 0;parent--) {
            shiftDowm(arr,parent,arr.length);
        }
    }

    private void shiftDowm(int[] arr, int parent, int length) {
        int child = parent * 2 + 1;
        while (child < length) {
            if ((child + 1) < length) {
                if (arr[child] < arr[child + 1]) {
                    child++;
                }
            }
            if (arr[parent] >= arr[child]) {
                break;
            }
            int tmp = arr[parent];
            arr[parent] = arr[child];
            arr[child] = tmp;
            parent = child;
            child = parent * 2 + 1;
        }
    }

 注:建堆的复杂度为O(N)

4、堆的插入

       总共需要两个步骤:

            (1)先将元素放入底层空间中(空间不够时需要扩容)

            (2)将最后新插入的节点向上调整,直到满足堆的性质

private void shiftUp(int child) {
        if (child >= size) {
            return;
        }
        int parent = (child - 1) / 2;
        while (child > 0 && parent > 0) {
            if (elementData[child] <= elementData[parent]) {
                break;
            }
            swap(elementData,parent,child);
            child = parent;
            parent = (child - 1) * 2;
        }
    }
private void swap(int[] elementData, int parent, int child) {
        int tmp = elementData[parent];
        elementData[parent] = elementData[child];
        elementData[child] = tmp;
    }

 5、堆的删除

         删除的一定是堆顶元素

         步骤如下:

            (1)将堆顶元素与堆中最后一个元素进行交换

            (2)将堆中有效数据个数减少一个

            (3)对堆顶元素进行向下调整

private int poll() {
        if (isEmpty()) {
            throw new RuntimeException("数组为空");
        }
        int value = elementData[0];
        swap(elementData,0,size - 1);
        size--;
        shiftDown(0);
        return value;
    }

6、用堆模拟实现优先级队列

import java.util.Arrays;

public class Heap {
    private int[] elementData;
    private int size;
    private int DEFAULT_CAPACITY = 10;

    public Heap() {
        this.elementData = new int[DEFAULT_CAPACITY];
        this.size = 0;
    }
    public Heap(int[] array) {
        this.elementData = Arrays.copyOf(array, array.length);
        this.size = array.length;
        int parent = (size - 1 - 1) / 2;
        for (int i = parent;i >= 0;i--) {
            shiftDown(i);
        }
    }
    private void shiftDown(int parent) {
        if (parent < 0) {
            return;
        }
        int child = parent * 2 + 1;
        while (child < size) {
            if (child + 1 < size) {
                if (elementData[child] < elementData[child + 1]) {
                    child++;
                }
            }
            if (elementData[parent]  > elementData[child]) {
                break;
            }
            swap(elementData,parent,child);
            parent = child;
            child = parent * 2 + 1;
        }

    }
    private void offer(int value) {
        if (isFull()) {
            elementData = Arrays.copyOf(elementData,elementData.length * 2);
        }
        elementData[size] = value;
        size++;
        shiftUp(size - 1);
    }
    private void shiftUp(int child) {
        if (child >= size) {
            return;
        }
        int parent = (child - 1) / 2;
        while (child > 0 && parent > 0) {
            if (elementData[child] <= elementData[parent]) {
                break;
            }
            swap(elementData,parent,child);
            child = parent;
            parent = (child - 1) * 2;
        }
    }
    private boolean isFull() {
        return size == elementData.length;
    }
    private int poll() {
        if (isEmpty()) {
            throw new RuntimeException("数组为空");
        }
        int value = elementData[0];
        swap(elementData,0,size - 1);
        size--;
        shiftDown(0);
        return value;
    }
    private int peek() {
        return elementData[0];
    }
    private boolean isEmpty() {
        return size == 0;
    }
    private void swap(int[] elementData, int parent, int child) {
        int tmp = elementData[parent];
        elementData[parent] = elementData[child];
        elementData[child] = tmp;
    }

    public static void main(String[] args) {
        int[] array = {27,15,19,18,28,34,65,49,25,37};
    }
}

二、 优先级队列

1、优先级队列的特性

 注:

        (1)PriorityQueue中放置的元素必须要能够比较大小,否则会抛出ClassCastException异常

         (2)不能插入null对象,否则会抛出NullPointerException

         (3)没有容量限制,可以插入任意多个元素,内部可以自动扩容

         (4)PriorityQueue底层使用了堆数据结构

         (5)PriorityQueue默认情况下是小堆

2、常用的函数


http://www.jnnr.cn/a/125075.html

相关文章

【Aseprite】制作Unity2D瓦片地图素材(平台游戏)

目录 前言&#xff1a; 一、创建画布 二、中心块的制作 三、中上块的制作 四、中下块的制作 五、左中块的制作 六、右中块的制作 七、角块的制作 八、小块的制作 九、洞穴的制作 十、斜坡的制作 十一、更陡峭的斜坡制作 十二、导出素材 前言&#xff1a; 本文章用于记录用…

md笔记上传到CSDN---Typora+SMMS+PicGo

当把md笔记上传到CSDN时&#xff0c;出现图片显示不出来的问题&#xff1a;[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传] 1.typora设置 文件->偏好设置->图像 勾选上传服务设定&#xff0c;选择上传服务为PicGo&#xff0c;选择PicGo路径 2.…

供应化学试剂Boc-NH-PEG-NH2,Boc-NH-PEG-amine,叔丁氧羰基PEG氨基

1、名称 英文&#xff1a;Boc-NH-PEG-NH2&#xff0c;Boc-NH-PEG-amine 中文&#xff1a;叔丁氧羰基-聚乙二醇-氨基 2、CAS编号&#xff1a;N/A 3、所属分类&#xff1a;Amine PEG Boc/Fmoc protected amine PEG 4、分子量&#xff1a;可定制&#xff0c;Boc-NH-PEG10-NH2…

本地搭建自己的电影网站,并发布公网访问 3-3

在之前的介绍中&#xff0c;我们向大家详细展示了如何在本地搭建起一个电影网站&#xff0c;并在本地进行了一些基本设置&#xff0c;使我们的电影网站看起来也能像点样。在我们本地网站搭建完成后&#xff0c;就需要使用cpolar建立的内网穿透数据隧道&#xff0c;将其发布到公…

2023最新SSM计算机毕业设计选题大全(附源码+LW)之java找学互助系统52568

最近大四学弟学妹们开始准备设计了&#xff0c;有一些问题问我&#xff0c;比如设计怎么做&#xff0c;有没有模板等等吧&#xff0c;大家都没有去学校&#xff0c;老师都是通过远程指导的&#xff0c;答辩也是远程答辩&#xff0c;这种情况下同学们不在一起&#xff0c;可能碰…

input输入框小写字母自动转换成大写字母的几种方式

input输入框输入小写字母自动转换成大写字母有两种方法&#xff1a; 1.用js onkeyup事件&#xff0c;即时把字母转换为大写字母&#xff1a; html里input加上 <input type"text" id"txt1" value"" onkeyup"toUpperCase(this)"/&g…

【C++天梯计划】1.5 深搜(DFS deep search)

文章目录什么是深搜&#xff1f;模拟深搜例题1&#xff1a;卒的遍历题目描述输入输出输入输出样例代码&#xff1a;例题2&#xff1a;走出迷宫的最少步数题目描述输入输出输入输出样例思路代码&#xff1a;&#x1f386;&#x1f389;&#x1f389;&#x1f389;&#x1f389;&…

【墨染】找特有姿态!基于【灵茶山艾府】题解的补充图解

脑筋急转弯 补充证明 灵茶山艾府找不到规律&#xff1f;请看图&#xff01;&#xff08;Python/Java/C/Go&#xff09; 一定要看链接里的图&#xff01;本题为看图的形象证明&#xff01;&#xff01; 定义: dp[n]dp[n]dp[n] 是 2n2\times n2n 矩形的 所有姿态 组成的状态。 …

ORB-SLAM2 ---- Initializer::Normalize函数

目录 1.函数作用 2.归一化的思想 3.归一化的数学基础 4.归一化Initializer::Normalize代码解读 4.1 构造函数 4.2 归一化的代码解读 1.函数作用 归一化特征点到同一尺度&#xff0c;作为后续normalize DLT的输入 2.归一化的思想 为什么要归一化&#xff1f; Ah0 矩阵A…

Pandas的数据结构

Pandas的数据结构 处理CSV 文件 CSV&#xff08;Comma-Separated Values&#xff0c;逗号分隔值&#xff0c;有时也称为字符分隔值&#xff0c;因为分隔字符也可以不是逗号&#xff09;&#xff0c;其文件以纯文本形式存储表格数据&#xff08;数字和文本&#xff09;。 Pan…

Cocoa-window

NSScreen screen存在mainScreen cout (int)[[NSScreen screens] count]; frame [[NSScreen mainScreen] frame]];//直接获取主屏的frame NSScreen* screen [[NSScreen screens] objectAtIndex:i];//获取索引为i的sreen的frame [windowController.window setFrame:screen…

猿创征文|宝藏工具篇|数字芯片设计,嵌入式开发,人工智能|没我可以,没你不行!

猿创征文&#xff5c;宝藏工具篇&#xff5c;数字芯片设计&#xff0c;嵌入式开发&#xff0c;人工智能&#xff5c;没我可以&#xff0c;没你不行&#xff01;引言&#x1f30f; 1. Xilinx Vivado SDK&#x1f30f; 2. PyCharm&#x1f30f; 3. Matlab&#x1f30f; 4. GVim &…

章节1 计算机体系结构

1.2.1-计算机硬件组成-CPU 计算机组成 台式机硬件-内部 台式机硬件-外部结构 CPU Center Processing Unit&#xff08;中央处理器/处理器&#xff09; 常见的电脑处理器&#xff1a; Inetl奔腾8086、酷睿i5 i7 i9&#xff1b;AMD 锐龙 常见的手机处理器&#xff1a; 高通…

手眼标定笔记

文章目录基本介绍&#xff1a;坐标系变换运算规则&#xff1a;关系运算说明&#xff1a;坐标系运算规则一&#xff1a;坐标系运算规则二&#xff1a;齐次坐标系&#xff1a;齐次坐标系下的坐标变换&#xff1a;眼在手外&#xff1a;眼在手内&#xff1a;解方程&#xff1a;- Ta…

若依前后端分离版获取部门表所有最子级部门并匹配部门名称生成excel

场景 若依前后端分离版手把手教你本地搭建环境并运行项目&#xff1a; https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/108465662 在上面搭建起来项目的基础上&#xff0c;业务需求是每天上报各个最子级部门的人数计划。 需要从部门表中动态获取当前所有最低…

cmd常用命令行

前言 最近在看《深入剖析Tomcat》&#xff0c;其中涉及了常见的dos命令&#xff0c;这里做一些简单记录&#xff0c;其实跟linux命令很像。 案例 .bat&#xff1a;批处理文件 rem&#xff1a;用于注释&#xff0c;解释器不会执行以rem命令开始的行 - pause&#xff1a;暂停…

学习CANopen --- [10] 汽车外接OBD模块原理

在某宝上搜索汽车OBD&#xff0c;可以发现很多卖OBD模块的&#xff0c;通过接入OBD模块可以增加车子本身没有的功能&#xff0c;如锁车升窗&#xff0c;行车自动落锁和后视镜折叠等&#xff0c;那么其实现原理是什么呢&#xff1f;使用时会造成亏电吗&#xff1f; 一 原理 OBD…

HyperLynx(二十九)高速串行总线仿真(一)

高速串行总线仿真&#xff08;一&#xff09; 1.高速串行接口 2.SERDES&#xff08;串行/解串器&#xff09;架构 3.高速串行链路仿真拓扑结构 4.高速串行信号仿真流程 5.IBIS-AMI模型 6.高速串行信号仿真方法 随着电子产品系统中数据传输速率的提高&#xff0c;互连传输带宽…

1995-2021全球经济自由度指数

1995-2021全球经济自由度指数 1、数据来源&#xff1a;美国传统jijin会 2、时间区间&#xff1a;1995-2021年 3、范围包括&#xff1a;全球 4、指标说明&#xff1a; 经济自由度指数&#xff0c;是由华尔街ribao和美国传统jijin会发布的年度报告&#xff0c;涵盖全球186个…

SpringMVC基于注解使用:拦截器

SpringMVC基于注解使用&#xff1a;拦截器 Springmvc拦截器 拦截器采用AOP的设计思想&#xff0c; 它跟过滤器类似&#xff0c; 用来拦截处理方法在之前和之后执行一些跟主业务没有关系的一些公共功能&#xff1a; 比如&#xff1a;可以实现:权限控制、日志、异常记录、记录方…
最新文章