当前位置: 首页 > news >正文

二、数据结构10:堆 模板题+算法模板(堆排序,模拟堆)

文章目录

  • 算法模板
    • 堆题目代码模板
    • 堆的原理
      • down操作理解:
      • up操作理解
      • 建堆操作
      • 关于heap_swap中存的映射数组理解(模拟堆题目中用到)
  • 模板题
    • 堆排序
      • 原题链接
      • 题目
      • 思路
      • 题解
    • 模拟堆
      • 原题链接
      • 题目
      • 思路
      • 题解

算法模板

堆题目代码模板

// h[N]存储堆中的值, h[1]是堆顶,x的左儿子是2x, 右儿子是2x + 1
// ph[k]存储第k个插入的点在堆中的位置
// hp[k]存储堆中下标是k的点是第几个插入的
int h[N], ph[N], hp[N], size;// 交换两个点,及其映射关系
void heap_swap(int a, int b)
{swap(ph[hp[a]],ph[hp[b]]);swap(hp[a], hp[b]);swap(h[a], h[b]);
}void down(int u)
{int t = u;if (u * 2 <= size && h[u * 2] < h[t]) t = u * 2;if (u * 2 + 1 <= size && h[u * 2 + 1] < h[t]) t = u * 2 + 1;if (u != t){heap_swap(u, t);down(t);}
}void up(int u)
{while (u / 2 && h[u] < h[u / 2]){heap_swap(u, u / 2);u >>= 1;}
}// O(n)建堆
for (int i = n / 2; i; i -- ) down(i);

堆的原理

以小根堆为例,小根堆中每个点小于等于左右儿子是递归定义的
在这里插入图片描述
在这里插入图片描述

down操作理解:

在这里插入图片描述
down完后:
在这里插入图片描述
代码实现:
在这里插入图片描述

up操作理解

在这里插入图片描述
up完后:
在这里插入图片描述

各种操作的实现思路:
在这里插入图片描述
在这里插入图片描述

建堆操作

在这里插入图片描述
建堆:一个一个插时间复杂度为O(nlogn)
使用上图中该方法从n/2 down到1,时间复杂度为O(n)

关于heap_swap中存的映射数组理解(模拟堆题目中用到)

由于该题目中需要对“第k个插入”的数进行处理,因此需要存两个数组来知道“第k个插入”的数在堆数组中的下标位置,在交换操作时也需要交换对应的映射。

ph[j]:第j个插入的点在堆数组中下标为k
hp[k]:堆里面下标为j的点对应的ph数组中的下标为j

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

模板题

堆排序

原题链接

https://www.acwing.com/problem/content/840/

题目

输入一个长度为 n
的整数数列,从小到大输出前 m
小的数。

输入格式
第一行包含整数 n
和 m

第二行包含 n
个整数,表示整数数列。

输出格式
共一行,包含 m
个整数,表示整数数列中前 m
小的数。

数据范围
1≤m≤n≤105

1≤数列中元素≤109
输入样例:

5 3
4 5 1 3 2

输出样例:

1 2 3

思路

建堆+down操作维护堆+删除堆顶元素操作,每次输出堆顶(h[1])即为当前最小值

题解

#include <iostream>
#include <algorithm>
using namespace std;const int N = 1e5 + 10, M = 1e5 + 10;
int h[N];
int n,m;
int sizeOfH;void down(int u){int t = u;if(u*2 <= sizeOfH && h[u*2]<h[t]) t = u*2;if(u*2+1 <= sizeOfH && h[u*2+1] < h[t]) t = u*2+1;if(u!=t){swap(h[t],h[u]);down(t);}} 
int main(){cin>>n>>m;for(int i=1;i<=n;i++) cin>>h[i];sizeOfH = n;//	建堆 for(int i=n/2; i ; i--) down(i);while(m--){printf("%d ",h[1]);h[1] = h[sizeOfH];sizeOfH--;down(1);}} 

模拟堆

原题链接

https://www.acwing.com/problem/content/841/

题目

维护一个集合,初始时集合为空,支持如下几种操作:

I x,插入一个数 x

PM,输出当前集合中的最小值;
DM,删除当前集合中的最小值(数据保证此时的最小值唯一);
D k,删除第 k
个插入的数;
C k x,修改第 k
个插入的数,将其变为 x

现在要进行 N
次操作,对于所有第 2
个操作,输出当前集合的最小值。

输入格式
第一行包含整数 N

接下来 N
行,每行包含一个操作指令,操作指令为 I x,PM,DM,D k 或 C k x 中的一种。

输出格式
对于每个输出指令 PM,输出一个结果,表示当前集合中的最小值。

每个结果占一行。

数据范围
1≤N≤105

−109≤x≤109

数据保证合法。

输入样例:

8
I -10
PM
I -10
D 1
C 2 8
I 6
PM
DM

输出样例:

-10
6

思路

在这里插入图片描述
实现堆的基本操作,但要注意的是题目中需要对“第k个插入”的数进行处理,因此需要维护ph和hp两个映射数组,并使用自定义的heap_swap方法。

题解

#include <iostream>
#include <algorithm>
#include <string.h>
using namespace std;const int N = 1e5 +10;int h[N],ph[N],hp[N],sizeOfH;
int n;void heap_swap(int a,int b){//因为操作中需要对“第k个插入”的数进行删除和修改操作,因此需要使用映射版的swap swap(ph[hp[a]],ph[hp[b]]);//ph[j]:第j个插入的点在堆数组中下标为k,hp[k]:堆里面下标为j的点对应的ph数组中的下标为j swap(hp[a],hp[b]);swap(h[a],h[b]);
}void down(int u){int t = u;if(u*2 <= sizeOfH && h[u*2]<h[t]) t = u*2;if(u*2+1 <= sizeOfH && h[u*2+1]<h[t]) t = u*2+1;if(t != u){heap_swap(t,u);down(t);}
}void up(int u){while(u/2 && h[u/2] > h[u]){ // 如果其父节点比该节点大,则将该节点up heap_swap(u/2,u);u/=2;}
}int main(){int m=0; // 全局中递增的唯一id 记录是第几个插入的数 cin>>n;while(n--){char op[10];int k,x;scanf("%s",op); // cin>>op;if(!strcmp(op,"I")){ //strcmp(const char *str1, const char *str2) 如果返回值小于 0,则表示 str1 小于 str2。如果返回值大于 0,则表示 str1 大于 str2。如果返回值等于 0,则表示 str1 等于 str2。cin>>x;sizeOfH++;m++;h[sizeOfH] = x;ph[m] = sizeOfH;hp[sizeOfH] = m;up(sizeOfH);} else if(!strcmp(op,"PM")) printf("%d\n",h[1]);else if(!strcmp(op,"DM")) {heap_swap(1,sizeOfH);sizeOfH--;down(1);}else if(!strcmp(op,"D")){cin>>k;k = ph[k];  // 找到第k个插入的数在堆数组中的坐标heap_swap(k,sizeOfH);sizeOfH--;down(k); // down和up其实只有其中一个起作用,但方便起见这样写 up(k);}else{cin>>k>>x;k = ph[k]; // 找到第k个插入的数在堆数组中的坐标h[k] = x;down(k);up(k);}}return 0; 
}

相关文章:

二、数据结构10:堆 模板题+算法模板(堆排序,模拟堆)

文章目录 算法模板堆题目代码模板堆的原理down操作理解&#xff1a;up操作理解建堆操作关于heap_swap中存的映射数组理解&#xff08;模拟堆题目中用到&#xff09; 模板题堆排序原题链接题目思路题解 模拟堆原题链接题目思路题解 算法模板 堆题目代码模板 // h[N]存储堆中的…...

W6100-EVB-PICO做DNS Client进行域名解析

前言 在上一章节中我们用W6100-EVB-PICO通过dhcp获取ip地址&#xff08;网关&#xff0c;子网掩码&#xff0c;dns服务器&#xff09;等信息&#xff0c;给我们的开发板配置网络信息&#xff0c;成功的接入网络中&#xff0c;那么本章将教大家如何让我们的开发板进行DNS域名解…...

【linux-网络】4层转发方法-iptable以及nginx

1.背景 有时候远程或者某些业务需要做转发就会用到iptables或者nginx&#xff0c;或者ss都可以 根据自己的情况去适配。 2.方法&#xff1a; 1&#xff09;iptables -把linux内核转发功能打开 echo "net.ipv4.ip_forward1" >> /etc/sysctl.conf -出入转发…...

vue复制文案,复制图片,黏贴图片

vue 实现复制文案&#xff0c;复制图片&#xff0c;在微信聊天框&#xff0c;黏贴为图片 //安装 cnpm i clipboard-all //引用 import clipboard from clipboard-all<!-- row.url 图片路径 --><div ref"foo" class"hidden"><img :src"…...

Web应急思路

Web应急思路 找到webshell --> 确定攻击者IP --> 回溯攻击者操作 --> 梳理整个攻击过程 1.寻找webshell方法 1.文件内容中的恶意函数 2.web日志中的webshell特征 3.贴合web业务中的URL来分析web日志 4.源码版本管理对比&#xff0c;注重修改或新增的脚本文件 5.统计…...

shell脚本清理redis模糊匹配的多个key,并计算释放内存大小

#!/bin/bash# 定义Redis服务器地址和端口 REDIS_HOST"localhost" REDIS_PORT6380# 获取Redis当前内存使用量&#xff08;以字节为单位&#xff09; function get_redis_memory_usage() {redis-cli -h $REDIS_HOST -p $REDIS_PORT INFO memory | grep "used_memo…...

python-MySQL数据库建表语句(需要连接数据库)转存为Excel文档-工作小记

将create table XXXXXX 转为指定Excel文档。该脚本适用于数据库表结构本地文档记录 呈现效果 代码 # -*- coding:utf-8 -*- # Time : 2023/8/2 15:14 # Author: 水兵没月 # File : MySQL建表_2_excel.py import reimport mysql.connector import pandas as pd db 库名 mydb …...

iOS Block介绍

文章目录 一、Block定义二、block为什么用copy修饰三、block使用时的注意事项四、使用 block时什么情况会发生引用循环&#xff0c;如何解决&#xff1f;五、在block内如何修改block外部变量&#xff1f;六、__block与__weak的区别 一、Block定义 目的就是能够直接存储一个代码…...

小程序安全性加固:如何保护用户数据和防止恶意攻击

第一章&#xff1a;引言 在当今数字化时代&#xff0c;移动应用程序的使用已经成为人们日常生活中的重要组成部分。小程序作为一种轻量级的应用程序形式&#xff0c;受到了广泛的欢迎。然而&#xff0c;随着小程序的流行&#xff0c;安全性问题也日益凸显。用户数据泄露和恶意攻…...

Ubuntu的tar命令详解

在 Ubuntu 中压缩文件夹可以使用 tar 命令。tar 可以将多个文件或文件夹打成一个包&#xff0c;并可选是否进行压缩&#xff0c;最常用的压缩方式是 gzip 和 bzip2。 常用的 tar 命令参数如下&#xff1a; -c&#xff1a;创建新的 tar 包&#xff1b; -x&#xff1a;解压 tar…...

使用elementplus实现文本框的粘贴复制

需求&#xff1a; 文本框仅用于显示展示数据并且用户可以进行复制&#xff0c;并不会进行修改和编辑&#xff0c; 注意点&#xff1a; 1.首先且文本为多行。所以不能使用普通的el-input&#xff0c;这种一行超出就会隐藏了&#xff0c;如果多行超出行数也会隐藏&#xff08;…...

计算机毕设 深度学习卫星遥感图像检测与识别 -opencv python 目标检测

文章目录 0 前言1 课题背景2 实现效果3 Yolov5算法4 数据处理和训练5 最后 0 前言 &#x1f525; 这两年开始毕业设计和毕业答辩的要求和难度不断提升&#xff0c;传统的毕设题目缺少创新和亮点&#xff0c;往往达不到毕业答辩的要求&#xff0c;这两年不断有学弟学妹告诉学长…...

devops(前端)

1.前言 前端的打包流程和后端的流程是一样的&#xff0c;只是打包的环境和制作的镜像有所不同&#xff0c;前端需要使用nodejs环境打包&#xff0c;镜像也是使用nginx镜像&#xff0c;因为用的是k8s的pod运行镜像&#xff0c;还需要使用configmap挂载nginx的配置&#xff0c;一…...

SpringBoot中MongoDB的使用

SpringBoot中MongoDB的使用 MongoDB 是最早热门非关系数据库的之一&#xff0c;使用也比较普遍&#xff0c;一般会用做离线数据分析来使用&#xff0c;放到内网的居 多。由于很多公司使用了云服务&#xff0c;服务器默认都开放了外网地址&#xff0c;导致前一阵子大批 MongoD…...

Spring学习之GOF的工厂模式

文章目录 工厂模式的三种形态简单工厂模式工厂方法模式抽象工厂模式&#xff08;了解&#xff09; 设计模式&#xff1a;一种可以杯冲覅利用的解决方案GoF&#xff08;Gang of Four&#xff09;&#xff0c;中文名——四人组《Design Patterns: Elements of Reusable Object-Or…...

整数转字符串

描述 用递归法将一个整数 n 转换成字符串。例如&#xff0c;输人 483&#xff0c;应输出字符串"483”。 n的位数不确定&#xff0c;可以是任意位数的整数。 输入 输入一个整数 输出 输出一个字符串 输入样例 1 483 输出样例 1 483 代码一&#xff08;如下&…...

【ARM Coresight 系列文章 2.4 - Coresight 寄存器:DEVARCH,DEVID, DEVTYPE】

文章目录 1.1 DEVARCH(device architecture register)1.2 DEVID(Device configuration Register)1.3 DEVTYPE(Device Type Identifier Register) 1.1 DEVARCH(device architecture register) DEVARCH 寄存器标识了coresight 组件的架构信息。 bits[31:21] 定义了组件架构&…...

Could not locate supplied template: react+ts搭建

1. reactts创建 我们在是用下create-react-app之前要下载一下 npm install create-react-app -g使用一下命令创建ts的react框架 create-react-app my-app --scripts-versionreact-scripts-ts 2. 遇见问题 我们用以上创建之后会提示一段代码选择“Y”之后发现我们创建的项目…...

fatal error C1128: 节数超过对象文件格式限制: 请使用 /bigobj 进行编译

问题 默认情况下&#xff0c;对象文件最多可存放 65,536 (2^16) 个可寻址的节。 /bigobj将该地址容量增加至 4,294,967,296 (2^32)。大多数模块将从来不会生成包含数超过 65,536 的 .obj 文件。 但是&#xff0c;计算机生成的代码或大量使用模板库的代码可能需要可存放更多节的…...

xml文件转成yolo中的txt文件

xml文件转成yolo中的txt文件 # codingutf-8import os import xml.dom.minidom import cv2 as cvdef xml_to_txt(indir, outdir):os.chdir(indir)xmls os.listdir(.)for i, file in enumerate(xmls):file_save file.split(.)[0] .txtfile_txt os.path.join(outdir, file_sa…...

装饰模式(Decorator Pattern)重构java邮件发奖系统实战

前言 现在我们有个如下的需求&#xff0c;设计一个邮件发奖的小系统&#xff0c; 需求 1.数据验证 → 2. 敏感信息加密 → 3. 日志记录 → 4. 实际发送邮件 装饰器模式&#xff08;Decorator Pattern&#xff09;允许向一个现有的对象添加新的功能&#xff0c;同时又不改变其…...

Qt/C++开发监控GB28181系统/取流协议/同时支持udp/tcp被动/tcp主动

一、前言说明 在2011版本的gb28181协议中&#xff0c;拉取视频流只要求udp方式&#xff0c;从2016开始要求新增支持tcp被动和tcp主动两种方式&#xff0c;udp理论上会丢包的&#xff0c;所以实际使用过程可能会出现画面花屏的情况&#xff0c;而tcp肯定不丢包&#xff0c;起码…...

解决Ubuntu22.04 VMware失败的问题 ubuntu入门之二十八

现象1 打开VMware失败 Ubuntu升级之后打开VMware上报需要安装vmmon和vmnet&#xff0c;点击确认后如下提示 最终上报fail 解决方法 内核升级导致&#xff0c;需要在新内核下重新下载编译安装 查看版本 $ vmware -v VMware Workstation 17.5.1 build-23298084$ lsb_release…...

在鸿蒙HarmonyOS 5中使用DevEco Studio实现录音机应用

1. 项目配置与权限设置 1.1 配置module.json5 {"module": {"requestPermissions": [{"name": "ohos.permission.MICROPHONE","reason": "录音需要麦克风权限"},{"name": "ohos.permission.WRITE…...

【Oracle】分区表

个人主页&#xff1a;Guiat 归属专栏&#xff1a;Oracle 文章目录 1. 分区表基础概述1.1 分区表的概念与优势1.2 分区类型概览1.3 分区表的工作原理 2. 范围分区 (RANGE Partitioning)2.1 基础范围分区2.1.1 按日期范围分区2.1.2 按数值范围分区 2.2 间隔分区 (INTERVAL Partit…...

有限自动机到正规文法转换器v1.0

1 项目简介 这是一个功能强大的有限自动机&#xff08;Finite Automaton, FA&#xff09;到正规文法&#xff08;Regular Grammar&#xff09;转换器&#xff0c;它配备了一个直观且完整的图形用户界面&#xff0c;使用户能够轻松地进行操作和观察。该程序基于编译原理中的经典…...

【Java学习笔记】BigInteger 和 BigDecimal 类

BigInteger 和 BigDecimal 类 二者共有的常见方法 方法功能add加subtract减multiply乘divide除 注意点&#xff1a;传参类型必须是类对象 一、BigInteger 1. 作用&#xff1a;适合保存比较大的整型数 2. 使用说明 创建BigInteger对象 传入字符串 3. 代码示例 import j…...

短视频矩阵系统文案创作功能开发实践,定制化开发

在短视频行业迅猛发展的当下&#xff0c;企业和个人创作者为了扩大影响力、提升传播效果&#xff0c;纷纷采用短视频矩阵运营策略&#xff0c;同时管理多个平台、多个账号的内容发布。然而&#xff0c;频繁的文案创作需求让运营者疲于应对&#xff0c;如何高效产出高质量文案成…...

Python实现简单音频数据压缩与解压算法

Python实现简单音频数据压缩与解压算法 引言 在音频数据处理中&#xff0c;压缩算法是降低存储成本和传输效率的关键技术。Python作为一门灵活且功能强大的编程语言&#xff0c;提供了丰富的库和工具来实现音频数据的压缩与解压。本文将通过一个简单的音频数据压缩与解压算法…...

​​企业大模型服务合规指南:深度解析备案与登记制度​​

伴随AI技术的爆炸式发展&#xff0c;尤其是大模型&#xff08;LLM&#xff09;在各行各业的深度应用和整合&#xff0c;企业利用AI技术提升效率、创新服务的步伐不断加快。无论是像DeepSeek这样的前沿技术提供者&#xff0c;还是积极拥抱AI转型的传统企业&#xff0c;在面向公众…...