【优先级队列 之 堆的实现】
文章目录
- 前言
- 优先级队列 PriorityQueue
- 优先队列的模拟实现
- 堆
- 堆的储存方式
- 堆的创建
- 建堆的时间复杂度
- 堆的插入与删除
- 总结
前言
优先级队列 PriorityQueue
概念:对列是先进先出的的数据结构,但有些情况,数据可能带有优先级,一般出队列时,可能需要优先级高的元素先出队列。所以像这种情况用队列不太合适:在手机上玩游戏时,如果有来电,系统应该优先处理打进来的电话。以前是来电显示充满整个画面,现在变成了一个小窗。
优先队列的模拟实现
PriorityQueue的底层使用了堆这种数据结构(PriorityQueue底层实现是一个完全二叉树,完全二叉树又分为大根堆和小根堆)
堆
概念:
小根堆:根节点比左右孩子都小。只考虑根和左右节点的关系,不考虑左右节点的哪个大。
大根堆:根节点比左右孩子都大
堆的储存方式
将元素存储到数组中后,可以根据二叉树章节的性质5对树进行还原。假设为节点在数组中的下标,则有: 如果为0,则表示的节点为根节点,否则节点的双亲节点为(i 1)/2
●如果2i+ 1小于节点个数,则节点的左孩子下标为2 门中1,否则没有左孩了
●如果2i+2小于节点个数,则节点的右孩子下标为21+ 2,否则没有右孩子
堆的创建
- 让parent标记需要调整的节点,child标记parent的左孩子(注意: parent如果有孩子一 定先是有左孩子)
- 如果parent的左孩子存在,即:child < size,进行以下操作, 直到parent的左孩子不存在
parent右孩子是否存在,存在找到左右孩子中最大的孩子,让child进行标记 - 将parent 与较大的孩子child比较,如果:
parent小于较大的孩子child,交换parent与较大的孩子child,交换完成之后,parent中小的元素向下移动,并继续向下调整,即parent = child; child = parent*2+1;然后继续
否则:退出循环。
public class TestHeap {//创建一个数组public int[] elem;public int useSize;//有效元素//构造方法给elem分配内存public TestHeap() {this.elem = new int[10];}//初始化elem数组,给elem传入元素public void initElem(int[] array){for (int i = 0; i < array.length; i++) {elem[i] = array[i];useSize++;}}/*** 创建大根堆的代码*/public void createHeap(){for (int parent =(useSize-1-1)/2 ; parent >=0 ; parent--) {siftDown(parent,useSize);}}/*** 向下调整* @param parent* @param len*///让child标记根的左孩子,如果左孩子大于数组长度则进行下面操作// 如果右孩子小于长度并且左孩子的值小于右孩子的值,让左孩子移到右孩子上private void siftDown(int parent,int len){int child = 2*parent+1;while(child < len){if (child+1 < len && elem[child] < elem[child+1]){child = child+1;}//此时child保存的是孩子节点中最大的值//如果左孩子大于根节点,两者的值交换。if (elem[child] > elem[parent]) {//和根节点交换int tmp = elem[child];elem[child] = elem[parent];elem[parent] = tmp;//交换完再换位置parent = child;//根节点移到孩子节点上child = 2*parent+1;//孩子节点再往下移}else{break;}}}
}public class Test {public static void main(String[] args) {TestHeap testHeap = new TestHeap();int[] array={27,15,19,18,28,34,65,49,25,37};testHeap.initElem(array);testHeap.createHeap();System.out.println("========");}
}
建堆的时间复杂度
因此:建堆的时间复杂度是0(N)
堆的插入与删除
堆的插入:
private void swap(int i,int j){int tmp = elem[i];elem[i] = elem[j];elem[j] = tmp;}//向上调整public void push(int val){if(isFull()){elem = Arrays.copyOf(elem,elem.length*2);}elem[usedSize] = val;siftUp(usedSize);usedSize++;}public boolean isFull(){return usedSize == elem.length;}public void siftUp(int child){int parent = (child-1)/2;while(child > 0){if (elem[child] > parent){swap(child,parent);child = parent;parent = (child-1)/2;}else{break;}}}
堆的删除
注意:这里的删除指的是删除堆顶的元素
- 将0下标的的堆顶元素和堆的最后一个元素交换
- 将堆的有效个数usedSize–
- 对堆进行向下调整
//删除堆顶元素public int pop(){if (empty()){return -1;}int oldVal = elem[0];swap(0,usedSize-1);usedSize--;siftDown(0,usedSize);return oldVal;}public boolean empty(){return usedSize == 0;}
总结
本章节学习如何实现一个堆,如何运用到向上调整,向下调整。
相关文章:

【优先级队列 之 堆的实现】
文章目录 前言优先级队列 PriorityQueue优先队列的模拟实现 堆堆的储存方式堆的创建建堆的时间复杂度堆的插入与删除 总结 前言 优先级队列 PriorityQueue 概念:对列是先进先出的的数据结构,但有些情况,数据可能带有优先级,一般出…...

Vue中$watch()方法和watch属性的区别
vue中$watch()和watch属性都是监听值的变化的,是同一个作用,但是有两个不同写法。 用法一: //注意:这种方法是监听不到对象的变化的。 this.$watch((newVal,oldVal)>{ }) 用法二: watch:{xxx:(newVal,oldVal)>…...
openssl3.2 - 官方demo学习 - test - certs - 001 - Primary root: root-cert
文章目录 openssl3.2 - 官方demo学习 - test - certs - 001 - Primary root: root-cert概述笔记备注END openssl3.2 - 官方demo学习 - test - certs - 001 - Primary root: root-cert 概述 实验前置条件为 openssl3.2 - linux脚本(.sh)调用openssl命令行参数的简单确认方法 …...

小程序商城能不能自己开发?
在数字化时代,小程序商城已经成为商家拓展销售渠道、提升品牌影响力的重要工具。那么,商家能否自己动手开发小程序商城呢?答案是肯定的。接下来,以乔拓云为例,为大家详细介绍如何自己搭建小程序商城。 首先,…...

GPTBots:利用FlowBot中的卡片和表单信息,提供丰富的客服体验
在当今的数字化时代,客户服务的形式和体验正在经历着前所未有的变革。传统的文字消息方式已经无法满足现代用户对于服务体验的多元化需求。那么,如何才能在这个信息爆炸的时代,让我们的服务方式更加个性化、多样化,从而提供更丰富…...
ERC20 解读
1.ERC20 什么叫做代币? 代币可以在以太坊中表示任何东西: 在线平台中的信誉积分游戏中一个角色的技能彩票卷金融资产类似于公司股份的资产像美元一样的法定货币一盎司黄金及更多... 以太坊的这种强大特点必须以强有力的标准来处理,对吗&a…...

C#,入门教程(31)——预处理指令的基础知识与使用方法
上一篇: C#,入门教程(30)——扎好程序的笼子,错误处理 try catchhttps://blog.csdn.net/beijinghorn/article/details/124182386 Visual Studio、C#编译器以及C#语法所支持的预处理指令,绝对是天才设计。 编译程序的时候会发现&am…...

Java SE:面向对象(下)
1. static关键字 静态区的特点:静态区里面的每一样东西都是唯一有且仅有一个的,如此时str1 "abc"即此时静态区里面已经创建了字符串abc并将abc地址赋给str1,后面在进行赋值也不会在静态区开辟一串新的"abc" 1.1 static修…...

搭建开源数据库中间件MyCat2-配置mysql数据库双主双从
mycat2官网:MyCat2 前言:mycat2下载地址无法访问,不知道是不是被DNS污染了,还是需要搭梯子访问,所以我只能找到1.21的版本进行安装。搭建mycat2的前提是搭建数据库主从复制。 架构:双主双从 配置…...

Oracle 19c rac集群管理 -------- 集群启停操作过程
Oracle rac集群启停操作过程 首先查看数据库的集群的db_unique_name SQL> show parameter nameNAME TYPE VALUE ------------------------------------ ----------- --------------------------- cdb_cluster_name …...

【Java】HttpServlet类中前后端交互三种方式(query string、form表单、JSON字符串)
在前后端的交互中,前端通过以下三种方式来与后端进行交互🌟 ✅query string ✅form表单 ✅JSON字符串 下面我们将书写这三种方式的后端代码并进行讲解 1、Query String QueryString即在url中写入键值对,一般用doGet方法进行交互 代码如下 …...

【深蓝学院】移动机器人运动规划--第2章 基于搜索的路径规划--笔记
0. Outline 1. Graph Search Basis Configuration Space等概念 机器人配置: 指机器人位置和所有点的表示。 DOF: 指用于表示机器人配置所需的最小的实数坐标的数量n。 C-space: 包含机器人n维所有配置的空间。 在C-space中机器人的pose是一个点。 机器人在C-space中被表示为一…...

安装向量数据库milvus可视化工具attu
使用docker安装的命令和简单就一个命令: docker run -p 8000:3000 -e MILVUS_URL{milvus server IP}:19530 zilliz/attu:v2.3.5sunyuhuasunyuhua-HKF-WXX:~/dockercom/milvus$ docker run -p 8000:3000 -e MILVUS_URL127.0.0.1:19530 zilliz/attu:latest yarn run…...

STM32标准库开发——串口发送/单字节接收
USART基本结构 串口发送信息 启动串口一的时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);初始化对应串口一的时钟,引脚,将TX引脚设置为复用推挽输出。 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); GPIO_InitTypeDef GPIO_In…...

jdk17新特性——文本块(即多行的字符串)增强
目录 一、文本块(即多行的字符串)概述二、文本块(即多行的字符串)示例2.1、jdk17之前 多行字符串处理方式2.2、jdk17及以后版本 多行字符串处理方式2.3、注意事项 三、文本块(即多行的字符串)转义字符示例3.1、jdk17及以后版本 多行字符串的转义字符处理方式示例一3.2、jdk17及…...

阿里云ECS使用docker搭建mysql服务
目录 1.确保正确安装好docker 2.安装mysql镜像 3.创建容器(设置端口映射、目录映射) 1.确保正确安装好docker 安装教程: 阿里云ECS(CentOS镜像)安装docker-CSDN博客https://blog.csdn.net/qq_62262918/article/details/135686614?spm10…...

Windows给docker设置阿里源
windows环境搭建专栏🔗点击跳转 Windows系统的docker设置阿里源 文章目录 Windows系统的docker设置阿里源1.获得镜像加速器2.配置docker 由于我们生活在中国大陆,所以外网的访问总是那么慢又困难,用docker拉取几兆的小镜象还能忍受ÿ…...

安裝火狐和穀歌流覽器插件FoxyProxy管理海外動態IP代理
代理生態系統擁有大量有用的實用程式,使海外代理IP代理設置的使用變得簡單起來。其中一種類型叫做代理管理工具,像FoxyProxy就是該工具集比較受歡迎的。 本文將全面解析FoxyProxy擴展的功能和特性、Foxyproxy怎麼下載、以及如何在穀歌流覽器和火狐流覽器…...
C++重新入门-函数重载
1.函数重载的定义 C函数重载(Function Overloading)是指在同一作用域内,可以定义多个函数,它们具有相同的名称但参数列表不同的特性。通过函数重载,可以使用相同的函数名来实现不同的操作,提高了代码的可读…...

niushop靶场漏洞查找-文件上传漏洞等(超详细)
实战漏洞-niushop 一.端口扫描 http://www.xxx.com/index.php?s/admin/login 这里查询到后面的url有且仅有一个,目测估计是后台 访问url 发现确实是后台 二、找漏洞 Sql注入漏洞1: 点击进去 修改id www.xxx.com/index.php?s/goods/goodslist&…...

铭豹扩展坞 USB转网口 突然无法识别解决方法
当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…...
蓝桥杯 2024 15届国赛 A组 儿童节快乐
P10576 [蓝桥杯 2024 国 A] 儿童节快乐 题目描述 五彩斑斓的气球在蓝天下悠然飘荡,轻快的音乐在耳边持续回荡,小朋友们手牵着手一同畅快欢笑。在这样一片安乐祥和的氛围下,六一来了。 今天是六一儿童节,小蓝老师为了让大家在节…...

自然语言处理——循环神经网络
自然语言处理——循环神经网络 循环神经网络应用到基于机器学习的自然语言处理任务序列到类别同步的序列到序列模式异步的序列到序列模式 参数学习和长程依赖问题基于门控的循环神经网络门控循环单元(GRU)长短期记忆神经网络(LSTM)…...

蓝桥杯3498 01串的熵
问题描述 对于一个长度为 23333333的 01 串, 如果其信息熵为 11625907.5798, 且 0 出现次数比 1 少, 那么这个 01 串中 0 出现了多少次? #include<iostream> #include<cmath> using namespace std;int n 23333333;int main() {//枚举 0 出现的次数//因…...
力扣-35.搜索插入位置
题目描述 给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) 的算法。 class Solution {public int searchInsert(int[] nums, …...

10-Oracle 23 ai Vector Search 概述和参数
一、Oracle AI Vector Search 概述 企业和个人都在尝试各种AI,使用客户端或是内部自己搭建集成大模型的终端,加速与大型语言模型(LLM)的结合,同时使用检索增强生成(Retrieval Augmented Generation &#…...

2025季度云服务器排行榜
在全球云服务器市场,各厂商的排名和地位并非一成不变,而是由其独特的优势、战略布局和市场适应性共同决定的。以下是根据2025年市场趋势,对主要云服务器厂商在排行榜中占据重要位置的原因和优势进行深度分析: 一、全球“三巨头”…...
GitHub 趋势日报 (2025年06月06日)
📊 由 TrendForge 系统生成 | 🌐 https://trendforge.devlive.org/ 🌐 本日报中的项目描述已自动翻译为中文 📈 今日获星趋势图 今日获星趋势图 590 cognee 551 onlook 399 project-based-learning 348 build-your-own-x 320 ne…...
React从基础入门到高级实战:React 实战项目 - 项目五:微前端与模块化架构
React 实战项目:微前端与模块化架构 欢迎来到 React 开发教程专栏 的第 30 篇!在前 29 篇文章中,我们从 React 的基础概念逐步深入到高级技巧,涵盖了组件设计、状态管理、路由配置、性能优化和企业级应用等核心内容。这一次&…...

VSCode 使用CMake 构建 Qt 5 窗口程序
首先,目录结构如下图: 运行效果: cmake -B build cmake --build build 运行: windeployqt.exe F:\testQt5\build\Debug\app.exe main.cpp #include "mainwindow.h"#include <QAppli...