优先级队列详解

一,优先级队列

什么是优先级队列呢,不知道大家了解过队列没有,队列是一种先进先出的数据结构,但是我们有时会想让优先级高的先出队列,所以我们出现了一种新的数据结构,我们实现两种主要功能得到优先级高的数据,和添加数据。

priorityQueue 就是我们的优先级队列,他实现了Queue接口,它底层使用了堆这种数据结构,而堆他是把一颗完全二叉树按顺序遍历的顺序把数据放到数组中,其中每个节点的父亲节点下标是 (i-1)/2,左子节点为2*i+1 ,右子节点为2*i+2。

我们来看priorityQueue中的主要方法

priority的构造方法。

优先级队列我们可以直接拿来创建大根堆和小根堆,那么什么是大根堆和小根堆呢

大根堆

小根堆

我们以完全二叉树形式,并且每个节点都比他两个子节点大,并且以顺序遍历的方式放到数组中就是我们的大根堆,反之就是小跟堆,那么怎么直接用priorityQueue创建大根堆呢。

public static void main(String[] args) {Queue<Integer> queue = new PriorityQueue<>();queue.offer()}

 我们如果直接用offer方法去添加的话是创建一个小根堆

public static void main(String[] args) {Queue<Integer> queue = new PriorityQueue<>();queue.offer(28);queue.offer(23);queue.offer(19);queue.offer(21);queue.offer(8);queue.offer(18);queue.offer(5);}

我们通过调试发现,建的堆确实是一个小根堆,priorityQueue底层实现建堆的时候是通过比较来处理要创建小根堆还是大根堆的,我们创建一个类来改变比较过程。

class IntCmp implements Comparator<Integer>{public int compare(Integer a,Integer b){return b-a;}
}
 Queue<Integer> queue = new PriorityQueue<>(new IntCmp());

我们把IntCmp对象传给优先级队的列构造方法。

这样我们就成功构建大根堆了。

二,优先级队列的模拟实现

下面我们来模拟下这个数据结构

在实现之前,我们来了解下什么是向上调整和向下调整,

向下调整

向下调整就是我们从一个节点开始,看当前节点的左节点和右节点,如果存在比当前节点大的节点的情况下,那么就是交换这两个节点

看这个图,24这个节点,左节点45比他大,就交换

因为交换的是24和45,所以我们不看12,看24这个节点,67大于24,交换。

到24节点和29比,29大交换,

这样我们就完成了一次向下调整。 

代码实现。

private void shiftDownBig(int root,int len) {int child = root*2+1;while (child<len){if(child+1<len && elem[child]<elem[child+1]){child++;}if (elem[child]>elem[root]){int tmp = elem[child];elem[child] = elem[root];elem[root] = tmp;root = child;child = root*2+1;}else {break;}}}private void shiftDownSmall(int root,int len) {int child = root*2+1;while (child<len){if(child+1<len && elem[child]>elem[child+1]){child++;}if (elem[child]<elem[root]){int tmp = elem[child];elem[child] = elem[root];elem[root] = tmp;root = child;child = root*2+1;}else {break;}}}

向上调整

向上调整也是差不多,从一个节点开始与父母节点比较,如果比父母节点大或者小就与它进行交换

我们找小的。

我们看24节点,24节点比自己的父亲节点小,交换, 

接下来24节点与其父亲节点67比较,24节点小,交换,

接下来24节点与45节点比较,24节点小,进行交换。

这下我们就完成了一次向上调整。

private void shiftUpBig(int child) {int parent = (child-1)/2;while (child>0){if(elem[parent]<elem[child]){int tmp = elem[parent];elem[parent] = elem[child];elem[child] = tmp;child = parent;parent = (child-1)/2;}else {break;}}}private void shiftUpSmall(int child) {int parent = (child-1)/2;while (child>0){if(elem[parent]>elem[child]){int tmp = elem[parent];elem[parent] = elem[child];elem[child] = tmp;child = parent;parent = (child-1)/2;}else {break;}}}

 接下来我们来创建大小根堆。

我们将会用两种方法分别创建大根堆和小根堆,所以我们在test创建4次数组,这样好看。

我们先来用向下调整实现大根堆和小根堆。 

用向下调整建大根堆其实就是多次利用向下调整去调整我们的二叉树,

还是这个图,如果我们要把它调整为大根堆,我们就要保证每个小数都是大根堆,我们从最后一个叶子节点看,找到它的父亲节点,例如67,再记录67的下标。

此时67的下标为3,我们让67向下调整,此时67这个子树是大根堆了,我让刚才记录的下标--,就来到了2下标,2再进行向下调整,此时2下标也为大根堆,2下标--,来到1,1向下调整,1下面也为大根堆,下标来到0,向下调整,此时全部都为大根堆,小根堆也一样,我们来看代码。

 public void createHeapBig1() {int c = elem.length-1;int p = (c-1)/2;while (p>=0){shiftDownBig(p,elem.length);p--;}}//向下调整建大根堆public void createHeapSmall1(){int c = elem.length-1;int p = (c-1)/2;while (p>=0){shiftDownSmall(p,elem.length);p--;}}//向下调整建小根堆

shiftDownSmall就是刚才我们实现的向下调整,只不过比较的时候大于号,小于号不同。

我们再用向上调整来实现大小根堆的创建。

这个是从最后一个数开始向上调整,调整好一个下标--,直到0下标,0下标不用向上调整。

    public void createHeapBig2(){int c = elem.length-1;while (c>0){shiftUpBig(c);c--;}}//向上调整建大根堆public void createHeapSmall2(){int c = elem.length-1;while (c>0){shiftUpSmall(c);c--;}}//向上调整建小根堆

 剩下的添加元素,获取元素就不难了

 public void push(int val) {elem = Arrays.copyOf(elem,elem.length+1);elem[elem.length-1] = val;shiftUpBig(elem.length-1);}/*** 出队【删除】:每次删除的都是优先级高的元素* 仍然要保持是大根堆*/public void pollHeap() {elem[elem.length-1] = elem[0];elem = Arrays.copyOf(elem,elem.length-1);shiftDownBig(0,elem.length);}/*** 获取堆顶元素* @return*/public int peekHeap() {int w = elem[0];elem[elem.length-1] = elem[0];elem = Arrays.copyOf(elem,elem.length-1);shiftDownBig(0,elem.length);return w;}

push一个新的元素的时候一定要向上调整,获取元素我们是把头和尾交换位置,把尾下标的访问权限封住,在从0进行向下调整即可 

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

螺蛳壳里做道场:老破机搭建的私人数据中心---Centos下Docker学习07(基于docker容器的防火墙及NAT企业实战)

7.1 网络准备 7.2 网络规划 1&#xff09;虚拟网络编辑器 点击右下方“更改设置”&#xff0c;点击“添加网络”假如vmnet3和vmnet4&#xff0c;然后分别选择vmnet3和vmnet4&#xff0c;设置为“仅主机模式”&#xff0c;按③处处理&#xff0c;去掉“使用DHCP”&#xff0c;…

ORA-19815 db_recovery_file_dest_size 100%

1、alert日志报错 ORA-19815 db_recovery_file_dest_size 100% 恢复区空间使用满 2、rm删除后操作系统空间使用&#xff0c;但V$RECOVERY_FILE_DEST记录的空间使用率仍然是满的 3、rman delete expired 归档日志后恢复正常 4、当然可以通过增大db_recovery_file_dest_size来临时…

牛客——xay loves or与 __builtin_popcount的使用

xay loves or 题目描述 登录—专业IT笔试面试备考平台_牛客网 运行思路 题目要求我们计算有多少个正整数 yy 满足条件 x \text{ OR } y sx OR ys。这里的“OR”是指按位或运算。为了理解这个问题&#xff0c;我们需要考虑按位或运算的性质。 对于任意两个位 a_iai​ 和 b_…

HUAWEI_HCIA_实验指南_Lib1.4_配置通过Telnet登录系统

一、原理概述 Telnet(Telecommunication Network Protocol)起源于ARPANET,是最早的Internet应用之一。 Telnet 通常用在远程登录应用中&#xff0c;以便对本地或远端运行的网络设备进行配置、监控和维护。如网络中有多台设备需要配置和管理&#xff0c;用户无需为每一台设备…

NUKE 15有哪些新的改进功能?影视后期特效合成NUKE 15 安装包分享 【Mac/win】

Nuke 15是一款由英国The Foundry公司开发的专业的合成软件&#xff0c;被广泛用于电影、电视和广告制作中的后期合成和特效制作。 Nuke 15拥有强大的功能和灵活性&#xff0c;可以帮助用户处理各种复杂的合成任务&#xff0c;包括图像修复、色彩校正以及粒子特效等。它具备高效…

Java项目实战II基于Java+Spring Boot+MySQL的高校学科竞赛平台

目录 一、前言 二、技术介绍 三、系统实现 四、文档参考 五、核心代码 六、源码获取 全栈码农以及毕业设计实战开发&#xff0c;CSDN平台Java领域新星创作者&#xff0c;专注于大学生项目实战开发、讲解和毕业答疑辅导。获取源码联系方式请查看文末 一、前言 随着高等教…

【JavaScript】JS核心语法及函数

文章目录 一、初识 JS二、JS 核心语法2-1 变量2-2 数据类型typeofString 对象 2-3 数组创建数组常用属性方法 2-4 运算符号加号运算符 减号运算符 -比较运算符逻辑运算符 2-5 控制语句for-inbreakcontinue 三、函数3-1 常用系统函数3-2 自定义函数函数声明函数调用 3-3 创建对象…

家里养有宠物应该用哪款宠物空气净化器比较好?哪款最能吸毛?

这不是国庆节刚过吗&#xff0c;我的小猫终于是平安的度过了在农村生活的时光&#xff0c;之前还担心会不会被爸妈嫌弃&#xff0c;这下好了&#xff0c;嫌弃也过了国庆节。 但是一把猫咪带回出租房&#xff0c;由于几天不在房子里待&#xff0c;猫咪对熟悉的环境又特别激动&a…

C语言贪吃蛇

#只讲逻辑不讲一些基础&#xff0c;基础大概过一遍就行# project-one: 无 (gitee.com)仓库里面有原代码 一、基础工作 1、先将你的编译器换成32位环境&#xff0c;也就是x86&#xff0c; 如果是控制台主机窗口则管&#xff0c;若不是需要改为控制台主机窗口 打开运行窗口后点…

构建宠物咖啡馆:SpringBoot框架的实现策略

1系统概述 1.1 研究背景 随着计算机技术的发展以及计算机网络的逐渐普及&#xff0c;互联网成为人们查找信息的重要场所&#xff0c;二十一世纪是信息的时代&#xff0c;所以信息的管理显得特别重要。因此&#xff0c;使用计算机来管理基于Spring Boot的宠物咖啡馆平台的设计与…

Authentication Lab | IP Based Auth Bypass

关注这个靶场的其它相关笔记&#xff1a;Authentication Lab —— 靶场笔记合集-CSDN博客 0x01&#xff1a;IP Based Auth Bypass 前情提要 有些开发人员为了图方便&#xff0c;会给站点设置一个 IP 白名单&#xff0c;如果访问站点的用户的 IP 在白名单内&#xff0c;则允许访…

PDSCH(物理下行共享信道)简介

文章目录 PDSCH&#xff08;物理下行共享信道&#xff09;简介1. Transport block CRC attachment2. LDPC base graph selection3. Code block segmentation And Code Block CRC Attachment4. Channel Coding5. Rate Matching6. Code Block Concatenation7. Scrambling8. Modul…

react自定义prolayout的展开收起

关于prolayout组件&#xff1a;ProLayout高级布局&#x1f3c6; 让中后台开发更简单 包含 table form 等多个组件。https://procomponents.ant.design/components/layout // tsx文件 import ProLayout from ant-design/pro-layout; ... const [collapsed,setCollapsed]useStat…

全网首发Windows Server 2019 AD 域控降级与退域的全面指南

哈喽大家好&#xff0c;欢迎来到虚拟化时代君&#xff08;XNHCYL&#xff09;。 “ 大家好&#xff0c;我是虚拟化时代君&#xff0c;一位潜心于互联网的技术宅男。这里每天为你分享各种你感兴趣的技术、教程、软件、资源、福利…&#xff08;每天更新不间断&#xff0c;福利…

微信小程序——婚礼邀请函

一、界面设计 首页&#xff1a; 精美的婚礼主题背景图&#xff0c;可能是新人的婚纱照或浪漫的插画。温馨的欢迎语&#xff0c;如 “欢迎参加我们的婚礼”。一个 “打开邀请函” 的按钮&#xff0c;引导用户进入邀请函详情页面。 邀请函详情页面&#xff1a; 顶部展示新人的照片…

【数据结构与算法】Divide and Conquer

4.4 Divide and Conquer 1) 概述 分治思想 将大问题划分为两个到多个子问题子问题可以继续拆分成更小的子问题&#xff0c;直到能够简单求解如有必要&#xff0c;将子问题的解进行合并&#xff0c;得到原始问题的解 之前学过的一些经典分而治之的例子 二分查找快速排序归并…

【C语言】数组练习

【C语言】数组练习 练习1&#xff1a;多个字符从两端移动&#xff0c;向中间汇聚练习2、二分查找 练习1&#xff1a;多个字符从两端移动&#xff0c;向中间汇聚 编写代码&#xff0c;演示多个字符从两端移动&#xff0c;向中间汇聚 练习2、二分查找 在⼀个升序的数组中查找指…

国庆作业

day1 1.开发环境 Linux系统GCCFDBmakefilesqlite3 2.功能描述 项目功能: 服务器&#xff1a;处理客户端的请求&#xff0c;并将数据存入数据库中&#xff0c;客户端请求的数据从数据库进行获取&#xff0c;服务器转发给客户端。 用户客户端&#xff1a;实现账号的注册、登…

【专题】数据库系统的基本原理

1. 数据库系统概述 1.1. 数据库系统的应用 电信业、银行业、金融业、销售业、联机的零售商、大学、航空业、人力资源、制造业等等。 1.2 数据库系统的概念 (1) 数据&#xff08;Data&#xff09; 数据是数据库存储的基本对象。是描述现实世界中各种具体事物或抽象概念的、可…

数据结构-5.1.树的定义和基本术语

一.树的基本概念&#xff1a; 1.根结点&#xff1a;最顶层的结点&#xff0c;有且仅有一个&#xff0c;没有前驱&#xff1b; 2.叶子结点&#xff1a;不能再有子结点&#xff0c;没有后继&#xff1b; 3.结点&#xff1a;用于存数据&#xff1b; 4.也有前驱和后继的说法&…