【堆的应用--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个最大的数据,就建小堆,反之就建小堆。   

 》》   》》》》》》》》》 今天分享的内容就结束了,下篇见》》》》》》》》》》》》》》》

关注博主,优质内容不断更新!!!

如有错误,还望指出!

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

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

相关文章

JVM 调优篇2 jvm的内存结构以及堆栈参数设置与查看

一 jvm的内存模型 2.1 jvm内存模型概览 2.2 pc计数器 它是一块很小的内存空间&#xff0c;集合可以忽略不记&#xff0c;也是运行速度最快的存储区域。不会随着程序的运行需要更大的空间。 在jvm规范中&#xff0c;每个线程都有它自己的程序计数器&#xff0c;是线程私有的&…

DIC技术助力新能源汽车主机厂力学测试研发与整车性能提升

在新能源汽车研发过程中&#xff0c;非接触式全视场应变DIC测量方案&#xff0c;越来越受到汽车主机厂的信赖与认可。传统接触式传感器&#xff0c;在精度、灵活性和数据处理能力上存在局限。DIC技术可提供精确、高效、全视场、便捷的非接触式测量解决方案。 在汽车研发阶段&a…

C语言知识体系思维导图

为了更清晰地描述C语言知识体系&#xff0c;笔者用一个结构化的思维导图来概括其主要组成部分。见下&#xff1a; 这个思维导图旨在提供一个全面而系统的视角&#xff0c;帮助学习者逐步构建扎实的C语言知识体系。随着学习的深入&#xff0c;可以根据个人兴趣和职业需求&#x…

《Diffusion Models Without Attention》CVPR2024

摘要 这篇论文探讨了在高保真图像生成领域&#xff0c;去噪扩散概率模型&#xff08;Denoising Diffusion Probabilistic Models, DDPMs&#xff09;的重要性。尽管DDPMs在捕捉复杂视觉分布方面表现出色&#xff0c;但在高分辨率图像生成上面临显著的计算挑战。现有的方法&…

计算机毕业设计 《计算机基础》网上考试系统的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍&#xff1a;✌从事软件开发10年之余&#xff0c;专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精…

大模型分离架构学习记录

GPU Direct GPU 网络的情况已经发生了很大变化。每个 GPU 都有自己的内部互联&#xff0c;例如 NVIDIA 的 A100 或 H800&#xff0c;它们内部的 NVLink 互联可以达到 600GB 甚至 900GB。这种内部互联与外部以太网网络集群设计之间存在耦合关系。GPU 是单机多网卡的&#xff0c…

创意无限:五款AI绘画应用,让艺术创作更简单

随着人工智能技术的不断进步&#xff0c;AI绘画已经成为一个不可忽视的现象。在短视频平台上&#xff0c;用户只需轻触屏幕&#xff0c;就能生成风格各异的画作&#xff0c;这种一键生成的特效迅速吸引了大量关注。AI绘画技术的快速发展&#xff0c;不仅让艺术创作变得更加便捷…

国产化数据库挑战及发展趋势

非国产数据库如Oracle、MySQL和MSSQL等在某些领域占据重要地位&#xff0c;但国产数据库的市场份额正在逐步提升&#xff0c;特别是在政策支持和市场需求的双重推动下&#xff0c;国产数据库的替代进程正在加速。 一、国产数据库市场规模 2024年中国数据库市场规模预计为543.1亿…

Python 数学建模——灰色关联度分析

文章目录 介绍原理代码实例 介绍 灰色关联度分析&#xff0c;可以反映两个序列 X ( k ) X(k) X(k) 和 Y ( k ) Y(k) Y(k) 之间的联系&#xff0c;用 r r r 表征。然而&#xff0c; r r r 的绝对大小并没有过多的意义&#xff0c;它的意义只在不同的 r r r 进行比较时体现。…

C语言蓝桥杯:语言基础

竞赛常用库函数 最值查询 min_element和max_element在vector(迭代器的使用) nth_element函数的使用 例题lanqiao OJ 497成绩分析 第一种用min_element和max_element函数的写法 第二种用min和max的写法 二分查找 二分查找只能对数组操作 binary_search函数&#xff0c;用于查找…

提升效率必备,掌握这些Shell文本处理技能!

Shell脚本是Linux系统里的一项基本功&#xff0c;就算它的语法看起来有点奇怪&#xff0c;读起来也不是特别顺畅&#xff0c;但在一些情况下&#xff0c;它仍然是最能干的解决办法。学好Shell脚本&#xff0c;不仅让你对Linux系统了解更深&#xff0c;还能让你手快地做好很多日…

使用程序方式获取与处理MySQL表数据

8.1  执行多条语句获取 MySQL 表数据 8.1.1  MySQL 中的常量 8.1.2  MySQL 中的变量 1&#xff0e;用户变量 用户可以在表达式中使用自己定义的变量&#xff0c;这样的变量称为用户变量。 用户变量在使用前必须定义和初始化&#xff0c;如果使用没有初始化的变量&#x…

外包干了三年,快要废了。。。

先简单说一下自己的情况&#xff0c;普通本科&#xff0c;在外包干了3年多的功能测试&#xff0c;这几年因为大环境不好&#xff0c;我整个人心惊胆战的&#xff0c;怕自己卷铺盖走人了&#xff0c;我感觉自己不能够在这样蹉跎下去了&#xff0c;长时间呆在一个舒适的环境真的会…

算法刷题:300. 最长递增子序列、674. 最长连续递增序列、718. 最长重复子数组

300. 最长递增子序列 1.dp定义&#xff1a;dp[i]表示i之前包括i的以nums[i]结尾的最长递增子序列的长度 2.递推公式&#xff1a;if (nums[i] > nums[j]) dp[i] max(dp[i], dp[j] 1); 注意这里不是要dp[i] 与 dp[j] 1进行比较&#xff0c;而是我们要取dp[j] 1的最大值…

JAVA 的excel数据批量导入解析 现在都用什么API工具 Apache POI 、EasyExcel 、easypoi有什么区别

&#x1f4dd;个人主页&#x1f339;&#xff1a;个人主页 ⏩收录专栏⏪&#xff1a;SpringBoot &#x1f339;&#x1f339;期待您的关注 &#x1f339;&#x1f339;&#xff0c;让我们共同进步&#xff01; 在Java中&#xff0c;处理Excel数据批量导入解析时&#xff0c;常…

高空抛物检测算法的应用场景解析

高空抛物事件频发&#xff0c;对公众安全构成严重威胁。无论是居民区还是商业中心&#xff0c;从高层建筑中丢弃物品都可能导致人员伤亡和财产损失。传统的监控手段多以事后追溯为主&#xff0c;无法在事发时及时预警和干预。为应对这一难题&#xff0c;视觉分析技术的发展为高…

全国历年高考真题2008-2024

目录 分享链接&#xff1a; ⬇️⬇️⬇️ 点击下载

单元测试之mock使用

一、简介 一般程序中A类的m1方法调用B类的m2方法&#xff0c;而B类的m2方法又调用了C类的m3方法以此类推等等&#xff0c;而其中的某个方法的一些数据又需要调用其它服务或者查询数据库&#xff0c;一般单元测试只针对某个功能进行测试&#xff0c;但是如上面的情况在做单元测试…

Day9 | Java框架 | SpringBoot

Day9 | Java框架 | SpringBoot SpringBoot简介入门程序概述起步依赖 基础配置配置文件格式&#xff1a;3种yaml语法规则yaml数据读取三种格式 多环境启动配置文件参数命令行参数多环境开发控制&#xff1a;Maven & SpringBoot 多环境兼容 配置文件分类&#xff1a;4种 整合…

蓝桥杯4. Fizz Buzz 经典问题

题目描述 给定一个整数 NN&#xff0c;从 1 到 NN 按照下面的规则返回每个数&#xff1a; 如果这个数被 3 整除&#xff0c;返回 Fizz。如果这个数被 5 整除&#xff0c;返回 Buzz如果这个数能同时被 3 和 5 整除&#xff0c;返回 FizzBuzz。如果这个数既不能被 3 也不能被 5…