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

【初阶数据结构】——堆排序和TopK问题

 =========================================================================

个人主页

代码仓库

C语言专栏

初阶数据结构专栏

Linux专栏

 =========================================================================

接上篇二叉树和堆的引入

========================================================================= 

目录

前言

建堆

插入数据向上调整算法建堆

移动数据向上调整算法建堆

无序数组从H-1层向上移动的向下调整算法建堆

堆排序

TOP-K问题


前言

上篇文章详细讲解了堆,最后在执行完整代码后我们发现在删除堆中的数据时可以实现排序,当然这不是偶然,一切都是有迹可循的,今天就来讲解下用堆来实现排序,以及使用堆排序解决TopK问题。

建堆

插入数据向上调整算法建堆

上篇文章中我们就实现了这个步骤,在主函数中创建了个数组然后将数组中的每个数据使用插入函数和向上调整算法函数依次插入动态开辟的空间中,每插入一个数据作为孩子和父亲相比较,根据大小交换位置,最终实现大/小堆。

插入函数

void HPPush(HP* php, HPDatatype x)
{assert(php);if (php->size == php->capacity){int newcapacity = php->capacity == 0 ? 4 : php->capacity * 2;HPDatatype* tmp = (HPDatatype*)realloc(php->a, sizeof(HPDatatype)*newcapacity);if (tmp == NULL){perror("realloc failed");exit(-1);}php->a = tmp;php->capacity = newcapacity;}php->a[php->size] = x;php->size++;HPadjustUp(php->a, php->size-1);
}

进入函数首先判断空间大小是否足够 ,不够的话使用realloc库函数开辟空间,开辟不成功直接退出,开辟成功的话赋值和修改size和容量。 

向上调整函数和交换函数 

void HPadjustUp(HPDatatype* a, int child)
{//找到父亲int parent = (child - 1) / 2;//根为0  当和根交换后child为0while (child > 0){//当child小时和父亲交换 建成小堆//当child大时和父亲交换 建成大堆if (a[parent] > a[child]){swap(&a[parent], &a[child]);child = parent;parent = (child - 1) / 2;}else{break;}}
}

 进入向上调整函数根据我们上篇内容提供父亲和孩子之间下标的关系,依次向上调整根据我们的需要和父亲孩子的大小关系,用交换函数实现大/小堆。

​
void swap(HPDatatype* x, HPDatatype* y)
{HPDatatype tmp = *x;*x = *y;*y = tmp;
}​

为防止局部变量出交换函数作用域被销毁,这里我们使用指针交换。

这种方式的缺点

1.需要动态开辟空间,造成空间浪费。

2.需要完整的堆实现的代码,比较麻烦不是很推荐。

我们可以使用下面的方法对上面的函数进行优化。


移动数据向上调整算法建堆

根据我们这个方法的名字就可以判断我们这个方法是不需要动态开辟额外的空间,只需要使用数组下标通过向上调整算法函数来实现。

实现代码

	for (int i = 1; i < n; i++){HPadjustUp(a, i);}

 这里我们将数组中的第一个数据作为一个堆通过下标的移动让后面的数字和前面的数字比较,也就相相当于前面的数字作为父亲后面的数字作为孩子,父亲和孩子使用向上调整函数进行调整实现堆。

像这样经过多次的移动就形成我们的堆。  


无序数组从H-1层向上移动的向下调整算法建堆

上篇文章我们介绍了向下移动的调整算法,但是这个算法有个前提就是除根外的左右子树都要是堆,但是我们这里给定一个无序数组先让这个数组模拟成堆,除根外左右子树有可能都不是堆,就无法实现向下调整算法,这样我们从倒数第一个非子叶结点开始向下调整也就是最后一个结点的父亲开始向下调整,我们直到数组在空间中是连续的,那我们从这个结点开始没向下调整依次,这个结点向前移动依次这样就将一个大堆分成各个小堆,完成向下调整了。

实现代码

for (int i = (n - 1 - 1) / 2; i >= 0; i--){AdjustDown(a, n, i);}

像这样经过多次的向下调整,最终就可以实现堆。 


堆排序

在实现堆排序之前我们先思考下升序和降序需要建什么堆?

我们这里直接给出答案:

升序:建大堆

降序:建小堆

问什么会是这样呢?

在上篇文章中堆的删除中,我们已经隐含的告诉大家了,如果我们要删除堆中的数据时直接向前移动数据会造成不是原有的大堆或者小堆,因此我们将根结点的数据和最后一个数据交换,两个子树依然是堆然后进行向下调整,size向前移动。我们不做删除这一步是不是就是排序!

实现代码

int end = n - 1;while (end > 0){swap(&a[end], &a[0]);AdjustDown(a, end, 0);end--;}

TOP-K问题

TOP-K问题:即求数据结合中前K个最大的元素或者最小的元素,一般情况下数据量都比较大。
比如:专业前10名、世界500强、富豪榜、游戏中前100的活跃玩家等。
对于Top-K问题,能想到的最简单直接的方式就是排序,但是:如果数据量非常大,排序就不太可取了(可能数据都不能一下子全部加载到内存中)。最佳的方式就是用堆来解决,基本思路如下:
1. 用数据集合中前K个元素来建堆
前k个最大的元素,则建小堆
前k个最小的元素,则建大堆
2. 用剩余的N-K个元素依次与堆顶元素来比较,不满足则替换堆顶元素将剩余N-K个元素依次与堆顶元素比完之后,堆中剩余的K个元素就是所求的前K个最小或者最大的元素。

void PrintTopK(const char* filename, int k)
{// 1. 建堆--用a中前k个元素建堆FILE* fout = fopen(filename, "r");if (fout == NULL){perror("fopen fail");return;}int* minheap = (int*)malloc(sizeof(int) * k);if (minheap == NULL){perror("malloc fail");return;}for (int i = 0; i < k; i++){fscanf(fout, "%d", &minheap[i]);}// 前k个数建小堆for (int i = (k-2)/2; i >=0 ; --i){AdjustDown(minheap, k, i);}// 2. 将剩余n-k个元素依次与堆顶元素交换,不满则则替换int x = 0;while (fscanf(fout, "%d", &x) != EOF){if (x > minheap[0]){// 替换你进堆minheap[0] = x;// 向下调整算法函数AdjustDown(minheap, k, 0);}}for (int i = 0; i < k; i++){printf("%d ", minheap[i]);}printf("\n");free(minheap);fclose(fout);
}// fprintf  fscanfvoid CreateNDate()
{// 造数据int n = 10000000;srand(time(0));const char* file = "data.txt";FILE* fin = fopen(file, "w");if (fin == NULL){perror("fopen error");return;}for (int i = 0; i < n; ++i){int x = (rand() + i) % 10000000;fprintf(fin, "%d\n", x);}fclose(fin);
}int main()
{//CreateNDate();PrintTopK("data.txt", 5);return 0;
}

文件操作知识忘了的话自己回顾下。

今天的内容到这里就结束了,感谢大家的观看!可以在评论区多多交流和探讨,指出我的错误!

下篇文章将讲解完全二叉树的实现!请大家敬请期待!!!

相关文章:

【初阶数据结构】——堆排序和TopK问题

个人主页 代码仓库 C语言专栏 初阶数据结构专栏 Linux专栏 接上篇二叉树和堆的引入 目录 前言 建堆 插入数据向上调整算法建堆 移动数据向上调整算法建堆 无序数组从H-1层向上移动的向下调整算法建堆 堆排序 TOP-K问题 前言 上篇文章详细讲解了堆&#xff0c;…...

LLM - 大模型速递 InternLM-20B 快速入门

目录 一.引言 二.模型简介 1.模型特性 2.模型评测 三.模型尝试 1.模型参数 2.generate 与 chat 3.模型微调 四.总结 一.引言 一早醒来国产开源大模型又添一员猛将&#xff0c;书生-浦语大模型 InternLM-20B 大模型发布并开源&#xff0c;这里字面翻译是实习生大模型&…...

探索AIGC人工智能(Midjourney篇)(四)

文章目录 Midjourney模特换装 Midjourney制作APP图标 Midjourney网页设计 Midjourney如何生成IP盲盒 Midjourney设计儿童节海报 Midjourney制作商用矢量插画 Midjourney设计徽章 Midjourney图片融合 Midjourney后缀参数 Midjourney模特换装 关键词生成模特照片 中国女性模特的…...

uni-app:跨页面传递数组

A页面&#xff1a; JSON.stringify() 是一个 JavaScript 内置的方法&#xff0c;用于将 JavaScript 对象或值转换为 JSON 字符串。 //查看详细信息 details(e){// console.log(e.currentTarget.dataset.id)var device JSON.stringify(e.currentTarget.dataset.id)uni.naviga…...

element 表格拖拽保存插件

这是以前看着一篇文章 1.下载包 npm install sortablejs --save 2.在页面中引入&#xff0c;或者全局引入 import Sortable from ‘sortablejs’ 3.在template中 <div id"second"><el-tableclass"threeTable":style"{height:tableData.len…...

通过内网穿透,在Windows 10系统下搭建个人《我的世界》服务器公网联机

文章目录 1. Java环境搭建2.安装我的世界Minecraft服务3. 启动我的世界服务4.局域网测试连接我的世界服务器5. 安装cpolar内网穿透6. 创建隧道映射内网端口7. 测试公网远程联机8. 配置固定TCP端口地址8.1 保留一个固定tcp地址8.2 配置固定tcp地址 9. 使用固定公网地址远程联机 …...

C++11异步任务轮子实现(header-only)

为什么写这个 C17异步任务需要future和promise配合使用&#xff0c;不是很喜欢那种语法。实现一个操作简洁的异步任务。 满足功能 异步任务超时控制get接口同步任务计时lambda回调任务重启 使用 #include "async_callback.h" #include <unistd.h> #includ…...

2023华为杯研究生数学建模竞赛选题建议+初步分析

如下为C君的2023华为杯研究生数学建模竞赛&#xff08;研赛&#xff09;选题建议初步分析 2023华为杯研究生数学建模竞赛&#xff08;研赛&#xff09;选题建议 提示&#xff1a;DS C君认为的难度&#xff1a;CE<D<F&#xff0c;开放度&#xff1a;CDE<F。 华为专项…...

多线程并发或线程安全问题如何解决

1、通过volatile关键字修饰变量&#xff0c;可以实现线程之间的可见性&#xff0c;避免变量脏读的出现&#xff0c;底层是通过限制jvm指令的重新排序实现的&#xff0c;适用于一个线程修改&#xff0c;多个线程读的场景。 2、通过synchronized锁&#xff08;任意对象&#xff0…...

深度学习——线性神经网络一

深度学习——线性神经网络一 文章目录 前言一、线性回归1.1. 线性回归的基本元素1.1.1. 线性模型1.1.2. 损失函数1.1.3. 解析解1.1.4. 随机梯度下降1.1.5. 用模型进行预测 1.2. 向量化加速1.3. 正态分布与平方损失1.4. 从线性回归到深度网络 二、线性回归的从零开始实现2.1. 生…...

利用大模型知识图谱技术,告别繁重文案,实现非结构化数据高效管理

我&#xff0c;作为一名产品经理&#xff0c;对文案工作可以说是又爱又恨&#xff0c;爱的是文档作为嘴替&#xff0c;可以事事展开揉碎讲清道明&#xff1b;恨的是只有一个脑子一双手&#xff0c;想一边澄清需求一边推广宣传一边发布版本一边申报认证实在是分身乏术&#xff0…...

Java抽象类和普通类区别、 数组跟List的区别

抽象类 Java中的抽象类是一种特殊的类&#xff0c;它不能被实例化&#xff0c;只能被继承。抽象类通常用于定义一些通用的属性和方法&#xff0c;但是这些方法的具体实现需要在子类中完成。抽象类中可以包含抽象方法和非抽象方法。 抽象方法是一种没有实现的方法&#xff0c;…...

Leetcode.2522 将字符串分割成值不超过 K 的子字符串

题目链接 Leetcode.2522 将字符串分割成值不超过 K 的子字符串 rating : 1605 题目描述 给你一个字符串 s s s &#xff0c;它每一位都是 1 1 1 到 9 9 9 之间的数字组成&#xff0c;同时给你一个整数 k k k 。 如果一个字符串 s s s 的分割满足以下条件&#xff0c;我们…...

成绩分析(蓝桥杯)

成绩分析 题目描述 小蓝给学生们组织了一场考试&#xff0c;卷面总分为 100 分&#xff0c;每个学生的得分都是一个 0 到 100 的整数。 请计算这次考试的最高分、最低分和平均分。 输入描述 输入的第一行包含一个整数 n (1≤n≤104 )&#xff0c;表示考试人数。 接下来 n 行…...

【多思路附源码持续更新】2023年华为杯(中国研究生数学建模)竞赛C题

赛题 若官网拥挤&#xff0c;数据集和赛题下载地址如下&#xff1a; https://download.csdn.net/download/weixin_47723732/88364777 历届优秀论文下载地址&#xff0c;可以做参考文章 https://download.csdn.net/download/weixin_47723732/88365222 论文万能模板下载地址 htt…...

基于STM32设计的校园一卡通(设计配套的手机APP)

一、功能介绍 【1】项目介绍 随着信息技术的不断发展,校园一卡通作为一种高效便捷的管理方式,已经得到了广泛的应用。而其核心部件——智能卡也被越来越多的使用者所熟知。 本文介绍的项目是基于STM32设计的校园一卡通消费系统,通过RC522模块实现对IC卡的读写操作,利用2…...

有了Spring为什么还需要SpringBoot呢

目录 一、Spring缺点分析 二、什么是Spring Boot 三、Spring Boot的核心功能 3.1 起步依赖 3.2 自动装配 一、Spring缺点分析 1. 配置文件和依赖太多了&#xff01;&#xff01;&#xff01; spring是一个非常优秀的轻量级框架&#xff0c;以IOC&#xff08;控制反转&…...

【记录】Python 之于 C/C++ 区别

记录本人在 Python 上经常写错的一些地方&#xff08;C/C 写多了&#xff0c;再写 Python 有点切换不过来&#xff09; 逻辑判断符号用 and、or、!可以直接 10 < num < 30 比较大小分支语句&#xff1a;if、elif、else使用 、-&#xff0c;Python 中不支持 、- - 这两个…...

【Vue-Element-Admin】dialog关闭回调事件

背景 点击导入按钮&#xff0c;调出导入弹窗&#xff0c;解析excel数据后&#xff0c;不点击【确认并导入】按钮&#xff0c;直接关闭弹窗&#xff0c;数据违背清理 实现 使用dialog的close回调函数&#xff0c;在el-dialog添加close&#xff0c;在methods中定义closeDialog…...

Ansible自动化:简化你的运维任务

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…...

webpack配置alias后eslint和ts无法识别

背景 我们在 webpack 配置 alias 后&#xff0c;发现项目中引入的时候&#xff0c;还是会报错&#xff0c;如下&#xff1a; 可以看到&#xff0c;有一个是 ts报错&#xff0c;还有一个是 eslint 报错。 解决 ts 报错 tsconfig.json {"compilerOptions": {...&q…...

小程序从无到有教学教程-- 01.重置华为云服务器Huawei Cloud EulerOS 2.0版本并且设置安全组

概述 专门拿了专栏来讲解&#xff0c;所以目录结构就比较简单了 文章目录 概述修改华为云操作系统选择Huawei Cloud EulerOS 2.0 镜像顺便配置华为安全组 修改华为云操作系统 这里选择华为最新的系统&#xff0c;不过也就2.0~ 选择Huawei Cloud EulerOS 2.0 镜像 这里记住密…...

js实现短信验证码一键登录

前言 短信验证码一键登录是一种方便快捷的登录方式&#xff0c;用户只需输入手机号码&#xff0c;然后接收到手机短信验证码并自动填入验证码框&#xff0c;即可完成登录操作。本文将介绍短信验证码一键登录的原理&#xff0c;并给出一个简单的示例说明。 短信验证码一键登录…...

vue2的基础知识巩固

一、定义&#xff1a;是一个渐进式的JavaScript框架 二、特点&#xff1a; 减少了大量的DOM操作编写 &#xff0c;可以更专注于逻辑操作分离数据和界面的呈现&#xff0c;降低了代码耦合度(前端端分离)支持组件化开发&#xff0c;更利于中大型项目的代码组织 vue2核心功能&a…...

echart离线地图下载地址

链接: 离线地图地址 https://datav.aliyun.com/portal/school/atlas/area_selector...

elk日志某个时间节点突然搜索不到了

elk日志某个时间节点突然搜索不到了,检查filebeat正常 Kibana手动上传数据: 响应: Error: Validation Failed: 1: this action would add [2] total shards, but this cluster currently has [2000]/[2000] maximum shards open 原因:ElasticSearch总分片数量导致的异常,ES…...

dbeaver 导出的sql文件,恢复数据库报错,Unknown command ‘\‘‘.

这是因为编码格式错误导致的&#xff0c; 加上这个即可 &#xff08;注意前后不能有空格&#xff09; --default-character-setutf8mb4...

Android.bp常用语法和预定义属性

介绍 Android.bp是Android构建系统中用于定义模块和构建规则的配置文件&#xff0c;它使用一种简单的声明式语法。以下是Android.bp的一些常见语法规则和约定&#xff1a; 注释&#xff1a; 单行注释使用//符号。 多行注释使用/和/包围。 和go语言相同 // 这是单行注释 /* 这是…...

close和fclose

在Linux系统中&#xff0c;close函数并不会主动调用fsync接口。close函数只是关闭了文件描述符&#xff0c;而不保证数据被写入到磁盘。如果你想确保数据被写入到磁盘&#xff0c;你需要在close函数之前调用fsync函数。这是因为Linux使用了缓存机制来提高磁盘的读写性能&#x…...

在已知的二维坐标里找到最接近的点

一、业务场景 最近在研发的项目&#xff0c;在做可视化层&#xff0c;在全球地图上&#xff0c;对我们的国家的陆地地图经纬度按照步长为1的间隔做了二维处理。在得到一组整数的点位信息后&#xff0c;需要将我们已有的数据库数据(业务项目)按照地址的经纬度&#xff0c;映射到…...

什么网站可以免费推广/常见的推广方式

$(document).ready(function(){$("p").click(function(){$(this).hide();}); }); jQuery 入口函数: $(document).ready(function(){// 执行代码 }); 或者 $(function(){// 执行代码 });JavaScript 入口函数: window.onload function () {// 执行代码 } jQuery 入口函…...

wordpress 画廊 插件/营销推广软件

在MyBatis中&#xff0c;<resultMap>和resultType都是定义查询结果映射的标签。 1. resultMap 如果查询出来的结果的列名和实体属性不一致&#xff0c;通过定义一个resultMap对列名和pojo属性名之间作一个映射关系 <resultMap> 则是自定义一个结果映射&#xff0…...

云课堂哪个网站做的好/免费的舆情网站app

这次又给大家带来了 RxJS 的相关文章&#xff0c;本文将结合实际项目需求和示例来给大家讲解 RxJS 的优缺点和最佳实践。本文作者&#xff1a;阳羡⚠️注意啦&#xff1a;字节跳动春招开始了&#xff0c;大家ready了吗&#xff1f;欢迎大家找我内推&#xff0c;最快方式进入到部…...

设计网站做的工作步骤是/2345纯净版推广包

【摘要】 计算机应用基础课是每所院校必须开设的一门强调实践性的基础课程,对其设计科学合理的考核模式,才能够真正的反应学生在计算机基础理论和基本操作技能上的真实能力和水平。对此进行了理论探讨,并设计了相应的考核模式及其组成。【关键词】 计算机应用基础;考核模式;上机…...

企业网站建设咨询/产品营销方案策划书

发现百度推出影视搜索&#xff08;http://movie.baidu.com/&#xff09;&#xff0c;没想到还要钱钱&#xff0c;30大洋/月&#xff0c;呵呵……我看这个服务我还是不会选择用了。不过&#xff0c;要真的生意好&#xff0c;保不准它还要开始对MP3下载收费&#xff0c;这是笑谈&…...

网站建设学费/长沙官网seo收费标准

文档部分代码不常用&#xff0c;所以整理一份常用的代码&#xff0c;便于CV 目录 ElementUI&#xff1a;组件库之Loading 加载...