【堆的应用--C语言版】
前面一节我们都已将堆的结构(顺序存储)已经实现,对树的相关概念以及知识做了一定的了解。其中我们在实现删除操作和插入操作的时候,我们还同时实现了建大堆(小堆)的向上(下)调整算法。
在这里我们需要补充:
我们上一节实现的算法中的向上调整算法的时间复杂度为O(n*log n),而向下调整算的时间复杂度为O(n)。所以我们就可以知道,在建堆的时候尽量选择时间复杂度较小的向下调整算法。
一.堆排序
小Tip:排升序,建大堆;排升序,建小堆。
1.版本一:
基于已有数组进行建堆,取堆顶元素完成排序。
注:该版本有一个前提,必须提供现有的数据结构堆。
//1.需要堆的数据结构 //2.空间复杂度 O(N) void HeapSort(int* a, int n) {HP hp; //创建一个堆for (int i = 0; i < n; i++){HPPush(&hp, a[i]); //将数组中每一个元素逐个插入堆中}//逐个取堆顶的元素int i = 0;while (!HPEmpty(&hp)){a[i++] = HPTop(&hp);//取堆顶的元素HPPop(&hp);//出堆}//销毁堆HPDestroy(&hp); }
基于前面我们已经实现过堆的顺序存储结构,在这里我们就只实现局部代码。实现思路我在代码的旁边已经进行了标注。
2.版本二:数组进行建堆,首尾交换,交换之后的堆尾从堆中删除掉,将堆顶数据向下调整选出次大的数据。
void HeapSort(int* a, i int n) {//先进行向下调整算法建堆for (int i = (n - 1 - 1) / 2; i >= 0; i--){AdjustDown(arr, i, n);}//循环 将堆顶数据进行交换,交换完将调整堆(堆中的要访问的底层数组的下标减1,在进行堆的调整的时候end还是 要调整的 堆中的元素个数)int end = end - 1;while (end){Swap(&a[0], &a[end]);AdustDwon(a, 0, end);end--;} }
实现思路已经在上面的代码中已经标注了。
二 .top-k问题
如果我们要在10个数据中,找前面3个最大的数据是多少,咋找? 如果我们要在100个数据中,找前面3个最大的数据是多少,咋找? 如果我们要在1000个数据中,找前面3个最大的数据是多少咋找? ……如果我们要在100000000000000000个数据中,找前面3个最大的数据是多少,咋找呢?
对于数据量少的,我们可以用前面所学的打擂台,冒泡排序,选择法排序,快速排序以及上面所讲的堆排序。但是对于数据量特别大的呢,我们如果还用上面所说的方法,那就太慢太麻烦了。现在我们所玩的游戏(有很多玩家)中找积分最多的前几个玩家?世界人口中找年龄最大的人?……用上面的方法是不是就很繁琐了。
所以对于这种类似的问题结合堆的性质我们就Top-k来进行排序。Top-k问题:即就是求数据集合中前k个最大或者最小的元素,一般情况下数据量都比较大。
#include <stdio.h>
#include <stdlib.h>
void Swap(int* x, int * y)
{int temp = *x;*x = *y;*y = temp;
}//可不用,见后面
void AdjustDown(int* arr, int parent, int size)
{int child = parent * 2 + 1;//左孩子while (child < size) //注意这里的条件{//找左右孩子中值最小的 小堆用> 大堆用<if (child + 1 < size && arr[child] > arr[child + 1]){child++;}//小堆用< 大堆用>if (arr[child] < arr[parent]){Swap(&arr[child], &arr[parent]);parent = child;child = parent * 2 + 1;}else{break;}}}//top-K 问题 求最大
void topk()
{int k = 0;printf("请你输入K>:");scanf("%d", &k);//以只读的方式打开文件const char *file = "data.txt";FILE* fout = fopen(file, "r");if (fout == NULL){perror("fopen fail!");exit(1);}//用动态内存内存的知识,申请k个整形单位的数组int* minHeap = (int*)malloc(sizeof(int) * k);if (minHeap == NULL){perror("malloc fail!");exit(2);}//从文件中读取数据for (int i = 0; i < k; i++){fscanf(fout, "%d", &minHeap[i]);}//取随机生成前k个数字进行建堆 利用向下调整算法进行建堆for (int i = (k-1-1)/2; i >= 0; i--){AdjustDown(minHeap, i, k); //建小堆}//将文件中剩余的数字和堆中的k个数据进行逐个比较,大的数字王进走,小的数字往出走int x = 0;while (fscanf(fout, "%d", &x)!=EOF){//如果此时读取到的数据大于堆顶数据,就将if (x > minHeap[0]){minHeap[0] = x; //此处也可以用Swap函数进行数据的交换AdjustDown(minHeap, 0, k);}}for (int i = 0; i < k; i++){printf("%d ", minHeap[i]);}fclose(fout);
}//先生成随机数字放在文件中
void CreatData()
{int n = 100000;srand((unsigned int)time(NULL));//利用时间戳进行堆随机数种子进行改变//以写的形式创建文件const char *file = "data.txt";FILE* fin = fopen(file, "w");if (fin == NULL){perror("fin fail!");return;}//向文件中写入用fprintf,向文件中写入数字for (int i = 0; i < n; i++){int x = (rand() + i) % 1000000;fprintf(fin, "%d\n", x);}fclose(fin);
}
int main()
{CreatData();topk();return 0;
}
实现的思路:
先实现自定义数据交换函数,向下调整算法(时间复杂度低,所以选择它),生成随机数的函数。
其次就是实现Top-K问题的核心了,先定义可以自定可在所有数字要找最大的k个数字的变量k,然后再以读的形式打开所生成随机数的那个文件,再就是开辟k个数据大小的数组空间。
然后先将文件中前k个数据存储在该数组中,再进行将数组中的k个元素进行建堆处理(此处建的是小堆)。随后循环读取文件中剩余的数据(直到遇到文件结束的标志),每一次将从文件中读取中的数据和小堆的堆顶进行比较大小,如果比堆顶数据大就将该值堆顶位置(或者交换)。于此同时之后每次还得数据调整(一直保持小堆)。读取完比较调整完之后,将最终数组中的数据打印在终端上。最终需要关闭文件哦!!!
注:
对于Top-k 问题如果求前K个最大的数据,就建小堆,反之就建小堆。
》》 》》》》》》》》》 今天分享的内容就结束了,下篇见》》》》》》》》》》》》》》》
关注博主,优质内容不断更新!!!
如有错误,还望指出!
相关文章:

【堆的应用--C语言版】
前面一节我们都已将堆的结构(顺序存储)已经实现,对树的相关概念以及知识做了一定的了解。其中我们在实现删除操作和插入操作的时候,我们还同时实现了建大堆(小堆)的向上(下)调整算法…...

【微信小程序】搭建项目步骤 + 引入Tdesign UI
目录 创建1个空文件夹,选择下图基础模板 开启/支持sass 创建公共style文件并引入 引入Tdesign UI: 1. 初始化: 2. 安装后,开发工具进行构建: 3. 修改 app.json 4. 使用 5. 自定义主题色 创建1个空文件夹,选择下…...

android系统源码12 修改默认桌面壁纸--SRO方式
1、aosp12修改默认桌面壁纸 代码路径 :frameworks\base\core\res\res\drawable-nodpi 替换成自己的图片即可,不过需要覆盖所有目录下的图片。 由于是静态修改,则需要make一下,重新编译。 2、方法二Overlay方式 由于上述方法有…...

Echarts可视化
echarts是一个基于javascripts的开源可视化图表库 画图步骤: 1.引入echarts.js文件 <script src" https://cdn.jsdelivr.net/npm/echarts5.5.1/dist/echarts.min.js"></script> 也可将文件下载到本地通过src引入。 2. 准备一个呈现图表的…...

验证linux gpu是否可用
通过torch验证 import torchprint(torch.__version__) # 查看torch当前版本号 print(torch.version.cuda) # 编译当前版本的torch使用的cuda版本号 print(torch.cuda.is_available()) # 查看当前cuda是否可用于当前版本的Torch,如果输出True,则表示可…...

JavaScript( 简介)
目录 含义 实例 js代码位置 1 外部引入js文件 2 在 HTML 中,JavaScript 代码必须位于 标签之间。 小结 含义 js是一门脚本语言,能够改变HTML内容 实例 getElementById() 是多个 JavaScript HTML 方法之一。 本例使用该方法来“查找” id"d…...

Linux中的编译器gcc/g++
目录 一、gcc与g的区别 1.gcc编译器使用 2.g编译器使用 二、gcc/g编译器编译源文件过程 1.预处理 2.编译 3.汇编 4.链接 三、静态库和动态库 1.库中的头文件作用 2.静态库 3.动态库 四、gcc编译器的一些选项命令 一、gcc与g的区别 gcc用于编译C语言代码ÿ…...

RK3568安装部署Docker容器
设置华为镜像源 sudo sed -i s/huaweicloud.com/ustc.edu.cn/g /etc/apt/sources.list更新索引 rootok3568:/home/forlinx# sudo apt-get update Hit:1 http://ports.ubuntu.com/ubuntu-ports focal InRelease Hit:2 http://ports.ubuntu.com/ubuntu-ports focal-updates InR…...

Ubuntu 常用指令和作用解析
Ubuntu 常用指令和作用解析 Ubuntu 是一种常见的 Linux 发行版,它利用了 Unix 的力量和开源软件的精神。掌握常用指令可以提高我们在使用 Ubuntu 时的效率。本文将介绍一些常见的指令及其用途。 目录 更新与安装软件文件与目录操作系统信息与资源监控用户与权限管…...

2024国赛数学建模C题完整论文:农作物的种植策略
农作物种植策略优化的数学建模研究(完整论文,持续更新,大家持续关注,更新见文末名片 ) 摘要 在本文中,建立了基于整数规划、动态规划、马尔科夫决策过程、不确定性建模、多目标优化、相关性分析、蒙特卡洛…...

【语音告警】博灵智能语音报警灯JavaScript循环播报场景实例-语音报警灯|声光报警器|网络信号灯
功能说明 本文将以JavaScript代码为实例,讲解如何通过JavaScript代码调用博灵语音通知终端 A4实现声光语音告警。主要博灵语音通知终端如何实现无线循环播报或者周期播报的功能。 本代码实现HTTP接口的声光语音播报,并指定循环次数、播报内容。由于通知…...

指针与函数(三)
三 .指向函数的指针 函数和数组一样,经系统编译后,其目标代码在内存中连续存放,其名字本身就是一个地址,是函数的入口地址。C语言中,指针可以指向变量,也可以指向函数。 指问函数的指针的定义格式为 类型名(*指针变量名)参数表 其中参数表为函数指针所…...

锐捷网络2025届校园招聘正式启动,【NTA6dni】!
锐捷网络2025届校园招聘正式启动,内推码[NTA6dni]。 原文链接点这 投递链接点这 祝大家面试顺利,offer多多~ 有问题大家可以评论,互相交流~...

共享内存喜欢沙县小吃
旭日新摊子好耶! 系统从0开始搭建过通信方案,本地通信方案的代码:System V IPC 里面有共享内存、消息队列、信号量 共享内存 原理 两个进程有自己的内存区域划分,共享内存被创建出的时候是归属操作系统的,还是通过…...

五、Build构建配置:jar包换名、自行定义编译规则
(1)jar包换名:finalName (2)自行定义编译规则(通常不用) Maven约定的规则就是java目录下写java代码,resources目录下写配置文件。 遵循规则,Maven会帮忙做编译。 如若…...

Html、Css3动画效果
文章目录 第九章 动画9.1 transform动画9.2 transition过渡动画9.3 定义动画 第九章 动画 9.1 transform动画 transform 2D变形 translate():平移函数,基于X、Y坐标重新定位元素的位置 scale():缩放函数,可以使任意元素对象尺…...

【AIStarter:AI绘画、设计、对话】零基础入门:Llama 3.1 + 千问2快速部署
对于希望在本地环境中运行先进语言模型的用户来说,Llama 3.1和千问2是非常不错的选择。本文将详细介绍如何在本地部署这两个模型,让你能够快速开始使用。 前期准备 确保你的计算机具备足够的存储空间和计算能力。安装Python环境以及必要的库࿰…...

多机编队—(1)ubuntu 配置Fast_Planner
文章目录 前言一、Could not find package ...二、使用error: no match for ‘operator’...总结 前言 最近想要做有轨迹引导的多机器人编队,打算采用分布式的编队架构,实时的给每个机器人规划出目标位置,然后通过Fast_Planner生成避障路径&…...

【数学建模经验贴】国赛拿到赛题后,该如何选题?
2024“高教社杯”全国大学生数学建模竞赛即将开赛。这可能是很多同学第一次参加国赛,甚至是第一次参加数学建模比赛。 那么赛题的公布也就意味着比赛的开始,也将是我们所要面对的第一个问题——选题。在国赛来临的前夕,C君想和大家聊一聊容易…...

如何快速融入大学课堂
快速融入大学课堂是适应大学生活的重要一步。以下是一些实用的建议,帮助你快速融入大学课堂并取得良好的学习效果。 ### 1. 提前准备 - **课前预习**:在上课前预习课程内容,了解基本概念和知识点,这样在课堂上更容易跟上老师的讲…...

el-table行编辑
需求:单点行编辑并且请求接口更新数据,表格中某几个字段是下拉框取值的,剩下的是文本域;展示的时候 需要区分下拉框编码还是中文 故障模式这个展示的是fault_mode编码,但要显示的文字fault_mode_chn 这点需要注意 <el-tablere…...

OpenSSL Windows编译
目录 1. 源码下载2. vs2022编译 1. 源码下载 源码地址 2. vs2022编译 (1) 将“VS2022安装目录VC\Auxiliary\Build\“设置为PATH环境变量,启动cmd命令行(一定要先设置环境变量)。 (2)在cmd下进入VS2013安装目录vs2022\VC\Auxiliary\Build&…...

优化LabVIEW中TCP通信速度的方法
在LabVIEW中,TCP通信速度较慢可能由多种因素导致,如数据包处理延迟、阻塞式读取或数据解析效率低等。通过调整读取模式、优化数据处理逻辑、以及使用并行处理结构,可以显著提升TCP通信的速度,使其接近第三方调试工具的表现。LabVI…...

【视频讲解】Python贝叶斯卷积神经网络分类胸部X光图像数据集实例
全文链接:https://tecdat.cn/?p37604 分析师:Yuanchun Niu 在人工智能的诸多领域中,分类技术扮演着核心角色,其应用广泛而深远。无论是在金融风险评估、医疗诊断、安全监控还是日常的交互式服务中,有效的分类算法都是…...

src/pyaudio/device_api.c:9:10: fatal error: portaudio.h: 没有那个文件或目录
(venv) shgbitaishgbitai-C9X299-PGF:~/pythonworkspace/ai-accompany$ pip install pyaudio sounddevice Collecting pyaudioDownloading PyAudio-0.2.14.tar.gz (47 kB)━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 47.1/47.1 kB 644.…...

移动端视频编辑SDK解决方案,AI语音识别添加字幕
对于众多Vlog创作者而言,繁琐的字幕添加过程往往成为提升内容质量的绊脚石。为了彻底改变这一现状,美摄科技凭借其深厚的AI技术积累与创新的移动端视频编辑SDK解决方案,推出了革命性的AI语音识别添加字幕功能,让视频创作更加高效、…...

WIN11 ESP32 IDF + VSCODE 环境搭建[教程向]
前言 目录 前言 安装ESP32-IDF VSCODE插件安装 编译测试 很多时候我们想学习一门新的技能,需要使用全新的开发环境,很多时候我们会在安装环境这个环节卡住很久,这里简单介绍一下ESP32VSCODE环境搭建。 安装ESP32-IDF https://dl.espre…...

Gemini AI 与 ChatGPT:哪个更适合为我策划婚礼?
我在六月订婚后,一心想着婚礼钟声,但在看到这些婚礼场地报价后,更像是警铃声响起。 “叮咚”已经被重新混音成“哗啦啦”——我需要帮助。 我甚至不知道如何 开始 计划婚礼。第一步是什么?我需要优先考虑什么?哪些任…...

log4j 同一线程隔离classloader下MDC信息不同问题解决 ThreadLocal问题分析
最近遇到日志文件记录错误的问题。一个任务的日志信息会被莫名的拆分到两个不同目录中。且有一个目录还是曾经执行过的任务的目录。经过分析,首先怀疑的是MDC没有清理的问题,这也是最直观的问题。因为任务是在线程池(fixedThreadPool)中运行的。由于线程…...

【2024-2025源码+文档+调试讲解】微信小程序的城市公交查询系统
摘 要 当今社会已经步入了科学技术进步和经济社会快速发展的新时期,国际信息和学术交流也不断加强,计算机技术对经济社会发展和人民生活改善的影响也日益突出,人类的生存和思考方式也产生了变化。传统城市公交查询管理采取了人工的管理方法…...