【数据结构】(6.2)堆的应用——Top-K问题(C语言)

系列文章目录

`


文章目录

  • 系列文章目录
  • 问题引入
  • 一、TopK 问题 是什么?
  • 二、TopK 问题解决思路
    • 2.1 TopK 思路
    • 2.2 随机产生数字
    • 2.2 完整代码
    • 2.3 验证结果


问题引入

TopK 问题 (在一堆数据里面找到前 K 个最大 / 最小的数)。


一、TopK 问题 是什么?

生活中也有很多实例,比如某外卖软件中有上千家店铺,我想选出当地好评最多的十家烤肉店,这时我们不用对所有数据进行排序,只需要取出前 K 个最大 / 最小数据。使用堆排序效率也更高。

二、TopK 问题解决思路

2.1 TopK 思路

思路一: 将数组从小到大排序,拿到数组前3个元素。但是可以发现这样时间复杂度太高,不可取。

思路二: 将元素全部放入一个结构中,然后弹出三个元素每次弹出的元素都是当前堆最小的,那么弹出的三个元素就是前最小的三个元素。
这种思路可以做,但是假设我有1000000个元素,只弹出前三个最小的元素,那么就要用到大小为1000000的堆。这么做**空间复杂度太高,**不建议用这种方法。

【最佳方法】-- 方法三:最佳的方式就是用堆来解决,基本思路如下:

1、用数据集合中前 K 个元素来建堆。

  • 前k个最大的元素,则建小堆
  • 前k个最小的元素,则建大堆

2、用剩余的 N-K 个元素依次与堆顶元素来比较,不满足则替换堆顶元素。将剩余 N-K 个元素依次与堆顶元素比完之后,堆中剩余的 K 个元素就是所求的前 K 个最小或者最大的元素。
————————————————

2.2 随机产生数字

//数据
void CreateNDate()
{// 造数据int n = 100000;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);
}

在这里插入图片描述

2.2 完整代码

向下调整法

		数据个数		要从哪里开始向下调整
void AdjustDown(HPDataType* a, int n, int parent)
{//第一步找出最小的孩子(然后和父亲交换)//假设法 走边孩子最小int minchild = parent * 2 + 1;while (minchild < n)	//当没到最后一个{//左孩子和右孩子(谁最小呢?)//1.前提右孩子存在吧		2.右孩子小于小孩子if (minchild + 1 < n && a[minchild + 1] < a[minchild]){minchild++;		//最小孩子下标更新为右孩子}//开始调整if (a[minchild] < a[parent]){Swap(&a[minchild], &a[parent]);parent = minchild;minchild = parent * 2 + 1;}else{break;}}}

TOP-K核心代码

//TOP-K
void testHeap2()
{//N个数找最大的前K个//选最大的K个,先建一个前个K个数的小堆//打开FILE* fout = fopen("data.txt", "r");if (fout == NULL){perror("fopen error");return;}	int k;printf("请输入k>:");scanf("%d", &k);int* kminheap = (int*)malloc(sizeof(int) * k);if (kminheap == NULL){perror("malloc fail");return;}int i = 0;for (i = 0; i < k; i++){fscanf(fout, "%d", &kminheap[i]);		//读入前k个数}//建k个数的小堆for (i = (k - 1 - 1) / 2; i >= 0; i++){AdjustDown(kminheap,k,0);}//读取剩下的N-K个数int x = 0;while (fscanf(fout, "%d", &x)>0){if (x > kminheap[0])	//读入的元素大于堆顶元素{kminheap[0] = x;	//覆盖AdjustDown(kminheap,k,0);			//向下调整}}printf("最大前%d个数:", k);for (int i = 0; i < k; i++){printf("%d ", kminheap[i]);}printf("\n");}

2.3 验证结果

我把其中两个数据,改的超级大
在这里插入图片描述

找最大的两个
在这里插入图片描述

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

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

相关文章

船舶雷达与导航系统选择7/8防水插座的原因分析

概述 船舶雷达与导航系统在现代航海中扮演着至关重要的角色&#xff0c;它们为船舶提供准确的导航信息&#xff0c;确保航行的安全和效率。在这些系统中&#xff0c;7/8防水插座的使用尤为重要&#xff0c;因为它们能够在恶劣的海上环境中提供稳定的电力和信号连接。接下来&am…

Outlook发送大文件的问题是什么?怎么解决?

Outlook不仅是一款电子邮件客户端&#xff0c;还包括日历、任务、笔记、联系人等功能&#xff0c;同时与Microsoft Office套件中的其他应用程序&#xff08;如Word、Excel、PowerPoint等&#xff09;集成紧密&#xff0c;方便用户在不同应用程序之间切换&#xff0c;提高工作效…

LLM - 神经网络的组成

1. 一个神经元的结构&#xff1a;即接受多个输入X向量&#xff0c;在一个权重向量W和一个偏执标量b的作用下&#xff0c;经过激活函数后&#xff0c;产生一个输出。 2. 一层神经网络的结构&#xff1a;该层网络里的每个神经元并行计算&#xff0c;得到各自的输出;计算方式是输入…

「植物大战僵尸杂交版」保姆级攻略大全以及下载指南

植物大战僵尸杂交版自推出以来&#xff0c;以其独特的植物组合和策略玩法&#xff0c;迅速赢得了玩家们的喜爱。如果你正准备加入这场植物与僵尸的战斗&#xff0c;或者已经在战斗中寻求突破&#xff0c;那么这份保姆级的攻略大全将是你的得力助手。同时&#xff0c;我们也提供…

【JavaWeb程序设计】Web基础-JavaScript

目录 一、函数与事件的使用 1. 编写一个html页面&#xff0c;使用Javascript完成数字的平方计算。 1.1 运行截图 1.2 JS代码 1.3 HTML代码 2. 要求文本框中只能输入字母 2.1 运行截图 2.2 下载jquery-3.4.1并引用 2.3 JS代码 2.4 HTML代码 3. 在文本框分别输入两个…

基于aardio web.view2库和python playwright包的内嵌浏览器自动化操作

通过cdp协议可以实现playwright操控webview。 新建Python窗口工程 修改pip.aardio 修改pip.aardio&#xff0c;并执行&#xff0c;安装playwright。 //安装模块 import process.python.pip; //process.python.path "python.exe";/* 安装模块。 参数可以用一个字…

Linux系统的基础知识和常用命令

1、什么是Linux&#xff1f; 是一种免费使用和自由传播的类UNIX操作系统&#xff0c;其内核由林纳斯本纳第克特托瓦兹于1991年10月5日首次发布&#xff0c;它主要受到Minix和Unix思想的启发&#xff0c;是一个基于POSIX的多用户、多任务、支持多线程和多CPU的操作系统。它能运行…

【面向就业的Linux基础】从入门到熟练,探索Linux的秘密(十)-git(2)

下面是一些git的常用命令和基本操作&#xff0c;可以当做平常的笔记查询&#xff0c;用于学习&#xff01;&#xff01;&#xff01; 文章目录 前言 一、git 二、git常用命令 总结 前言 下面是一些git的常用命令和基本操作&#xff0c;可以当做平常的笔记查询&#xff0c;用于…

【MindSpore学习打卡】应用实践-计算机视觉-深入解析 Vision Transformer(ViT):从原理到实践

在近年来的深度学习领域&#xff0c;Transformer模型凭借其在自然语言处理&#xff08;NLP&#xff09;中的卓越表现&#xff0c;迅速成为研究热点。尤其是基于自注意力&#xff08;Self-Attention&#xff09;机制的模型&#xff0c;更是推动了NLP的飞速发展。然而&#xff0c…

pandas,dataframe使用笔记

目录 新建一个dataframe不带列名带列名 dataframe添加一行内容查看dataframe某列的数据类型新建dataframe时设置了列名&#xff0c;则数据类型为object dataframe的保存保存为csv文件保存为excel文件 dataframe属于pandas 新建一个dataframe 不带列名 df pd.DataFrame() 带…

GuLi商城-商品服务-API-品牌管理-效果优化与快速显示开关

<template><div class"mod-config"><el-form :inline"true" :model"dataForm" keyup.enter.native"getDataList()"><el-form-item><el-input v-model"dataForm.key" placeholder"参数名&qu…

java集合(1)

目录 一.集合概述 二. 集合体系概述 1. Collection接口 1.1 List接口 1.2 Set接口 2. Map接口 三. ArrayList 1.ArrayList常用方法 2.ArrayList遍历 2.1 for循环 2.2 增强for循环 2.3 迭代器遍历 一.集合概述 我们经常需要存储一些数据类型相同的元素,之前我们学过…

C++ 仿QT信号槽二

// 实现原理 // 每个signal映射到bitset位&#xff0c;全集 // 每个slot做为signal的bitset子集 // signal全集触发&#xff0c;标志位有效 // flip将触发事件队列前置 // slot检测智能指针全集触发的标志位&#xff0c;主动运行子集绑定的函数 // 下一帧对bitset全集进行触发清…

【C++】 解决 C++ 语言报错:Segmentation Fault

文章目录 引言 段错误&#xff08;Segmentation Fault&#xff09;是 C 编程中常见且令人头疼的错误之一。段错误通常发生在程序试图访问未被允许的内存区域时&#xff0c;导致程序崩溃。本文将深入探讨段错误的产生原因、检测方法及其预防和解决方案&#xff0c;帮助开发者在…

4.2 投影

一、投影和投影矩阵 我们以下面两个问题开始&#xff0c;问题一是为了展示投影是很容易视觉化的&#xff0c;问题二是关于 “投影矩阵”&#xff08;projection matrices&#xff09;—— 对称矩阵且 P 2 P P^2P P2P。 b \boldsymbol b b 的投影是 P b P\boldsymbol b Pb。…

2024年7月5日 (周五) 叶子游戏新闻

老板键工具来唤去: 它可以为常用程序自定义快捷键&#xff0c;实现一键唤起、一键隐藏的 Windows 工具&#xff0c;并且支持窗口动态绑定快捷键&#xff08;无需设置自动实现&#xff09;。 卸载工具 HiBitUninstaller: Windows上的软件卸载工具 《乐高地平线大冒险》为何不登陆…

江汉大学刘春萌同学整理的wifi模块 上传mqtt实验步骤

一.固件烧录 1.打开安信可官网 2.点击wifi模组系列的ESP8266 3.点击各类固件后选择固件号1471下载 4.打开烧录工具将下载的二进制文件导入并将后面的起始地址写为0x00000,下面勾选40mhz QIO 8Mbit点击start下载即可 二.本地部署mqtt服务器(windows) 1.下载mosquitto后有一个m…

Java并发编程知识整理笔记

目录 ​1. 什么是线程和进程&#xff1f; 线程与进程有什么区别&#xff1f; 那什么是上下文切换&#xff1f; 进程间怎么通信&#xff1f; 什么是用户线程和守护线程&#xff1f; 2. 并行和并发的区别&#xff1f; 3. 创建线程的几种方式&#xff1f; Runnable接口和C…

Qt实现流动的管道效果代码示例

在现代图形用户界面&#xff08;GUI&#xff09;应用程序中&#xff0c;动态效果可以显著增强用户体验。本文将介绍如何使用Qt框架实现一个流动的管道效果。我们将通过自定义QWidget来绘制管道&#xff0c;并使用定时器来实现流动效果。 1. 准备工作 首先&#xff0c;确保你已…

HMI 的 UI 风格创造奇迹

HMI 的 UI 风格创造奇迹