利用编程思维做题之最小堆选出最大的前10个整数
1. 理解问题
我们需要设计一个程序,读取 80,000 个无序的整数,并将它们存储在顺序表(数组)中。然后从这些整数中选出最大的前 10 个整数,并打印它们。要求我们使用时间复杂度最低的算法。
由于数据量很大,直接排序的时间复杂度较高,因此我们需要一个更高效的算法。最小堆 是一种合适的选择,因为它能够在 O(n log k) 的时间复杂度内完成最大 10 个整数的选取。
2. 输入输出
- 输入:通过键盘输入 80,000 个整数。
- 输出:打印出最大的 10 个整数。
3. 数据结构
我们使用一个最小堆来存储当前最大 10 个数。堆的根节点是堆中最小的元素,插入新元素时,如果新元素大于堆的根节点,则替换根节点并调整堆结构。这样,在遍历完所有 80,000 个数之后,堆中的 10 个元素就是最大的 10 个整数。
最小堆的数据结构如下:
struct MinHeap {
int* arr; // 存储堆的数组
int size; // 当前堆的大小
int capacity; // 堆的最大容量
};
4. 制定策略
- 建堆:我们通过一个大小为 10 的最小堆来存储当前最大的 10 个数。
- 遍历输入:每读取一个数,检查该数是否大于堆顶元素,如果大于,则替换堆顶并调整堆。
- 输出结果:遍历完所有数后,堆中将包含最大的 10 个数。
- 时间复杂度:由于堆的操作是 O(log k),每次插入操作的时间复杂度为 O(log 10),因此整个过程的时间复杂度是 O(n log 10) ≈ O(n)。
5. 实现代码
5.1 完整代码
#include <stdio.h>
#include <stdlib.h>
// 最小堆的结构体定义
struct MinHeap {
int* arr; // 存储堆的数组
int size; // 当前堆的大小,即有数值的个数
int capacity; // 堆的最大容量
};
// 创建最小堆
struct MinHeap* createMinHeap(int capacity) {
// 定义一个MinHeap结构体大小的指针,指向一个堆
struct MinHeap* heap = (struct MinHeap*)malloc(sizeof(struct MinHeap));
heap->arr = (int*)malloc(sizeof(int) * capacity);
heap->size = 0;
heap->capacity = capacity;
return heap;
}
// 交换两个元素
void swap(int* a, int* b) {
int temp = *a;
*a = *b;
*b = temp;
}
// 维护堆的性质(向下调整)
void heapify(struct MinHeap* heap, int index) {
int left = 2 * index + 1;
int right = 2 * index + 2;
int smallest = index;
// 找出最小的元素
if (left < heap->size && heap->arr[left] < heap->arr[smallest]) {
smallest = left;
}
if (right < heap->size && heap->arr[right] < heap->arr[smallest]) {
smallest = right;
}
// 如果最小元素不是当前元素,交换并继续调整
if (smallest != index) {
swap(&heap->arr[index], &heap->arr[smallest]);
heapify(heap, smallest);
}
}
// 维护堆的性质(向上调整)
void upheapify(struct MinHeap* heap, int index) {
while (index > 0 && heap->arr[index] < heap->arr[(index - 1) / 2]) {
swap(&heap->arr[index], &heap->arr[(index - 1) / 2]);
index = (index - 1) / 2;
}
}
// 插入元素到堆中
void insert(struct MinHeap* heap, int value) {
if (heap->size < heap->capacity) {
// 如果堆未满,直接插入
heap->arr[heap->size] = value;
upheapify(heap, heap->size); // 插入后需要向上调整
heap->size++;
} else if (value > heap->arr[0]) {
// 如果堆已满且当前值大于堆顶元素,则替换堆顶
heap->arr[0] = value;
heapify(heap, 0); // 替换堆顶后需要进行堆化
}
}
// 打印堆中的前 10 个最大值
void printTop10(struct MinHeap* heap) {
// 最小堆中的前 10 个最大值已经存储在堆中,直接打印
for (int i = 0; i < heap->size; i++) {
printf("%d ", heap->arr[i]);
}
printf("\n");
}
// 主程序
int main() {
struct MinHeap* heap = createMinHeap(10); // 创建一个容量为 10 的最小堆
int value;
printf("请输入 80000 个整数(每输入一个整数后按 Enter,输入 80000 个数):\n");
// 读取 80,000 个整数
for (int i = 0; i < 80000; i++) {
scanf("%d", &value);
insert(heap, value); // 将输入的值插入堆中
}
// 打印堆中的前 10 个最大值
printf("最大的 10 个整数是:\n");
printTop10(heap);
// 释放堆内存
free(heap->arr);
free(heap);
return 0;
}
6. 代码说明
- 结构体定义:我们定义了一个
MinHeap
结构体来表示最小堆,包含一个数组arr
存储堆的元素,size
表示当前堆的大小,capacity
是堆的最大容量(即 10)。 - 堆的操作:
createMinHeap
:创建一个新的最小堆。swap
:交换堆中的两个元素。heapify
:维护堆的性质,确保堆仍然是最小堆。insert
:将新元素插入堆。如果堆未满,直接插入。如果堆已满并且新元素大于堆顶元素,则替换堆顶并重新调整堆。printTop10
:打印堆中的前 10 个最大值(即堆中的元素)。
- 主程序:
- 通过
scanf
读取 80,000 个整数,并将它们插入最小堆。 - 插入操作将保证堆中始终保存着最大的 10 个元素。
- 最后输出堆中的元素,即为最大的 10 个整数。
- 通过
7. 模拟过程
假设输入为:
2 5 8 12 20 10 1 35 27 50 41 39 70 80 90 23 17 16 13 11 ...
程序将使用最小堆的结构,维护堆中最大 10 个数。每读取一个新数,程序将插入最小堆,并保证堆的大小不超过 10。当所有 80,000 个数输入完成后,堆中将包含最大的 10 个数。
8. 运行结果
假设输入的数据中最大的 10 个数为:90, 80, 70, 50, 41, 39, 35, 27, 23, 20
,程序输出:
最大的 10 个整数是:90 80 70 50 41 39 35 27 23 20
注意,此代码只会获取最大的10个数,但不会排序这10个数。
9. 时间和空间复杂度分析
- 时间复杂度:
- 建堆的时间复杂度:每次插入一个元素时,最小堆的插入操作为 O(log 10) = O(1),因此整个过程的时间复杂度是 O(n),其中
n
为 80,000。
- 建堆的时间复杂度:每次插入一个元素时,最小堆的插入操作为 O(log 10) = O(1),因此整个过程的时间复杂度是 O(n),其中
- 空间复杂度:最小堆需要 O(10) 的空间来存储最大 10 个数,因此空间复杂度为 O(1),即常数空间。
10. 总结
通过使用最小堆,我们能够以 O(n) 的时间复杂度找到并输出最大的 10 个数。这种方法比直接排序更高效,尤其是当数据量很大时。
相关文章:
利用编程思维做题之最小堆选出最大的前10个整数
1. 理解问题 我们需要设计一个程序,读取 80,000 个无序的整数,并将它们存储在顺序表(数组)中。然后从这些整数中选出最大的前 10 个整数,并打印它们。要求我们使用时间复杂度最低的算法。 由于数据量很大,直…...
详解MVC架构与三层架构以及DO、VO、DTO、BO、PO | SpringBoot基础概念
🙋大家好!我是毛毛张! 🌈个人首页: 神马都会亿点点的毛毛张 今天毛毛张分享的是SpeingBoot框架学习中的一些基础概念性的东西:MVC结构、三层架构、POJO、Entity、PO、VO、DO、BO、DTO、DAO 文章目录 1.架构1.1 基本…...
Unity C# 影响性能的坑点
c用的时间长了怕unity的坑忘了,记录一下。 GetComponent最好使用GetComponent<T>()的形式, 继承自Monobehaviour的函数要避免空的Awake()、Start()、Update()、FixedUpdate().这些空回调会造成性能浪费 GetComponent方法最好避免在Update当中使用…...
工作学习:切换git账号
概括 最近工作用的git账号下发下来了,需要切换一下使用的账号。因为是第一次弄,不熟悉,现在记录一下。 打开设置 路径–git—git remotes,我这里选择项是Manage Remotes,点进去就可以了。 之后会出现一个输入框&am…...
量化交易系统开发-实时行情自动化交易-8.量化交易服务平台(一)
19年创业做过一年的量化交易但没有成功,作为交易系统的开发人员积累了一些经验,最近想重新研究交易系统,一边整理一边写出来一些思考供大家参考,也希望跟做量化的朋友有更多的交流和合作。 接下来会对于收集整理的33个量化交易服…...
Scala习题
姓名,语文,数学,英语 张伟,87,92,88 李娜,90,85,95 王强,78,90,82 赵敏,92,88,91 孙涛,…...
结构方程模型(SEM)入门到精通:lavaan VS piecewiseSEM、全局估计/局域估计;潜变量分析、复合变量分析、贝叶斯SEM在生态学领域应用
目录 第一章 夯实基础 R/Rstudio简介及入门 第二章 结构方程模型(SEM)介绍 第三章 R语言SEM分析入门:lavaan VS piecewiseSEM 第四章 SEM全局估计(lavaan)在生态学领域高阶应用 第五章 SEM潜变量分析在生态学领域…...
OpenCV图像基础处理:通道分离与灰度转换
在计算机视觉处理中,理解图像的颜色通道和灰度表示是非常重要的基础知识。今天我们通过Python和OpenCV来探索图像的基本组成。 ## 1. 图像的基本组成 在数字图像处理中,彩色图像通常由三个基本颜色通道组成: - 蓝色(Blue&#x…...
C++ 类和对象(类型转换、static成员)
目录 一、前言 二、正文 1.隐式类型转换 1.1隐式类型转换的使用 2.static成员 2.1 static 成员的使用 2.1.1static修辞成员变量 2.1.2 static修辞成员函数 三、结语 一、前言 大家好,我们又见面了。昨天我们已经分享了初始化列表:https://blog.c…...
【网络安全设备系列】12、态势感知
0x00 定义: 态势感知(Situation Awareness,SA)能够检测出超过20大类的云上安全风险,包括DDoS攻击、暴力破解、Web攻击、后门木马、僵尸主机、异常行为、漏洞攻击、命令与控制等。利用大数据分析技术,态势感…...
Linux介绍与安装指南:从入门到精通
1. Linux简介 1.1 什么是Linux? Linux是一种基于Unix的操作系统,由Linus Torvalds于1991年首次发布。Linux的核心(Kernel)是开源的,允许任何人自由使用、修改和分发。Linux操作系统通常包括Linux内核、GNU工具集、图…...
BGE-M3模型结合Milvus向量数据库强强联合实现混合检索
在基于生成式人工智能的应用开发中,通过关键词或语义匹配的方式对用户提问意图进行识别是一个很重要的步骤,因为识别的精准与否会影响后续大语言模型能否检索出合适的内容作为推理的上下文信息(或选择合适的工具)以给出用户最符合…...
鸿蒙NEXT开发案例:文字转拼音
【引言】 在鸿蒙NEXT开发中,文字转拼音是一个常见的需求,本文将介绍如何利用鸿蒙系统和pinyin-pro库实现文字转拼音的功能。 【环境准备】 • 操作系统:Windows 10 • 开发工具:DevEco Studio NEXT Beta1 Build Version: 5.0.…...
CTF之密码学(栅栏加密)
栅栏密码是古典密码的一种,其原理是将一组要加密的明文划分为n个一组(n通常根据加密需求确定,且一般不会太大,以保证密码的复杂性和安全性),然后取每个组的第一个字符(有时也涉及取其他位置的字…...
修改插槽样式,el-input 插槽 append 的样式
需缩少插槽 append 的 宽度 方法1、使用内联样式直接修改,指定 width 为 30px <el-input v-model"props.applyBasicInfo.outerApplyId" :disabled"props.operateCommandType input-modify"><template #append><el-button click…...
UPLOAD LABS | PASS 01 - 绕过前端 JS 限制
关注这个靶场的其它相关笔记:UPLOAD LABS —— 靶场笔记合集-CSDN博客 0x01:过关流程 本关的目标是上传一个 WebShell 到目标服务器上,并成功访问: 我们直接尝试上传后缀为 .php 的一句话木马: 如上,靶场弹…...
【css实现收货地址下边的平行四边形彩色线条】
废话不多说,直接上代码: <div class"address-block" ><!-- 其他内容... --><div class"checked-ar"></div> </div> .address-block{height:120px;position: relative;overflow: hidden;width: 500p…...
缓存方案分享
不知道大家平常更新缓存是怎么做的,但是大部分时候都是更新数据的同时更新缓存,今天和同事一起聊到一个缓存方案的问题,感觉很有趣、非常精妙,记录一下。 基于此本文将介绍几种常见的缓存更新策略,包括简单的缓存覆盖…...
第四十篇 DDP模型并行
摘要 分布式数据并行(DDP)技术是深度学习领域中的一项重要技术,它通过将数据和计算任务分布在多个计算节点上,实现了大规模模型的并行训练。 DDP技术的基本原理是将数据和模型参数分割成多个部分,每个部分由一个计算节点负责处理。在训练过程中,每个节点独立计算梯度,…...
软件测试面试之常规问题
1.描述一下测试过程 类似题目:测试的生命周期 思路:这是一个“范围”很大的题目,而且回答时间一般在3分钟之内,不可能非常详细的描述整个过程,因此答题的思路要从整体结构入手,不要过细。为了保证答案的准确性,可以引…...
《图像形态学运算全解析:原理、语法及示例展示》
简介: 本文详细介绍了图像形态学中的多种运算,包括腐蚀、膨胀、开运算、闭运算、形态学梯度运算、礼帽运算以及黑帽运算。分别阐述了各运算的原理、语法格式,并通过 Python 代码结合具体示例图片(如erode.JPG、dilate.JPG、close.…...
双十一线上服务调用链路追踪SkyWalking实战分析
序言 随着电商行业的飞速发展,双十一购物节已成为全球最大的购物狂欢节之一。在双十一期间,电商平台需要处理海量的用户请求和订单,这对系统的稳定性和性能提出了极高的要求。为了确保系统在高并发环境下的稳定运行,对线上服务的…...
网络安全究竟是什么? 如何做好网络安全
网络安全是如何工作的呢? 网络安全结合多层防御的优势和网络。每个网络安全层实现政策和控制。授权用户访问网络资源,但恶意参与者不得进行攻击和威胁。 我如何受益于网络安全? 数字化改变了我们的世界。我们的生活方式、工作、玩耍,和学习都发生了变化。每个组织希望提供…...
【C++】入门【一】
本节目标 一、C关键字(C98) 二、命名空间 三、C的输入输出 四、缺省函数 五、函数重载 六、引用 七、内联函数 八、auto关键字(C11) 九、范围for(C11) 十、指针空值nullptr(C11) 一.…...
【ArcGIS Pro实操第11期】经纬度数据转化成平面坐标数据
经纬度数据转化成平面坐标数据 数据准备ArcGIS操作步骤-投影转换为 Sinusoidal1 投影2 计算几何Python 示例 另:Sinusoidal (World) 和 Sinusoidal (Sphere) 的主要区别参考 数据准备 数据投影: 目标投影:与MODIS数据相同(Sinu…...
python学opencv|读取图像
【1】引言 前序学习了使用matplotlib模块进行画图,今天开始我们逐步尝试探索使用opencv来处理图片。 【2】学习资源 官网的学习链接如下: OpenCV: Getting Started with Images 不过读起来是英文版,可能略有难度,所以另推荐一…...
ffmpeg RTP PS推流
要实现 CRtpSendPs 类,使其能够将 H264 数据通过 RTP PS 流推送到指定的 URL,并支持 TCP 和 UDP 传输方式,您需要使用 FFmpeg 库。以下是该类的实现示例,包括必要的初始化、推流和退出函数。 步骤 初始化 FFmpeg 库:…...
Rust语言俄罗斯方块(漂亮的界面案例+详细的代码解说+完美运行)
tetris-demo A Tetris example written in Rust using Piston in under 500 lines of code 项目地址: https://gitcode.com/gh_mirrors/te/tetris-demo 项目介绍 "Tetris Example in Rust, v2" 是一个用Rust语言编写的俄罗斯方块游戏示例。这个项目不仅是一个简单…...
NUMA架构及在极速网络IO场景下的优化实践
NUMA技术原理 NUMA架构概述 随着多核CPU的普及,传统的对称多处理器(SMP)架构逐渐暴露出性能瓶颈。为了应对这一问题,非一致性内存访问(NUMA, Non-Uniform Memory Access)架构应运而生。NUMA架构是一种内存…...
Brain.js 用于浏览器的 GPU 加速神经网络
Brain.js 是一个强大的 JavaScript 库,它允许开发者在浏览器和 Node.js 环境中构建和训练神经网络 。这个库的目的是简化机器学习模型的集成过程,使得即使是没有深厚机器学习背景的开发者也能快速上手 。 概述 Brain.js 提供了易于使用的 APIÿ…...
可免费注册的网站/广东企业网站seo哪里好
iTEST大学外语测试与训练系统FLTRP iTEST大学外语测试与训练系统(以下简称iTEST)是为高校提供英语试题库资源和在线评测服务的综合测试管理平台。平台提供大学英语四六级考试、英语专业四八级考试、研究生英语入学考试等高质量模拟题库和基础训练题库,支持学生进行词…...
温州做网站就来温州易富网络/弹窗广告最多的网站
父窗体Form1 子窗体Form2 Form1中有一个datagridview控件和一添加按钮,Form2中有一个Text控件和一个保存按钮 要求点击Form1窗体上的添加按钮,弹出Form2,再text里面输入内容,点击保存自动关闭Form2,刷新Form1中datagri…...
wordpress首页只能是page/关键词指数查询
别人文章参考:https://blog.csdn.net/kkevinyang/article/details/80539940 第三类错误:supervisord进程被占用的错误 查询进程,kill掉在重启 ps -ef | grep supervisord 报错信息: Exited too quickly (process log may have…...
懒人做图网站/太原seo霸屏
Java反射是Java语言一个很重要的特征,简单剖析下反射的定义、原理、使用、性能及应用场景。 (一)定义 程序运行时,允许改动程序结构或变量类型,这种语言称为动态语言。java不属于动态语言,但提供了RTTI&…...
广州商城网站建设报价/百度app客服电话
一、Context 全局的环境对象,提供了很多方便的操作,帮助我们快速的获取数据,进行一些常规的操作。 1.1、获取路径 getFilesDir()等同于/data/data/包名/files/ File file new File(getFilesDir(),"info.txt"); 1.2、缓存文件路径 getCacheDir()等同于/da…...
怎么在国外网站开发客户/怎么做好销售
近日服务器上的运行的一个站点经常性出现500错误。查了下服务器负载,负载正常。而后查询了下nginx记录的站点运行错误日志,发现提示Too many open files。因为站点静态文件居多,而且http请求结束后,打开的文件描述符会被自动关闭&…...