【数据结构】堆的应用——Top-K

目录

前言:

一、Top-K问题描述:

二、不同解决思路实现:

①.排序法:

②.直接建堆法:

③.K堆法

总结:

前言:

        上篇文章我们学习了二叉树的顺序存储结构,并且对于实际使用中所常用的顺序存储结构——堆的各个接口进行实现。这篇文章我们将对堆的实际应用进行更加深入的研究。

一、Top-K问题描述:

        Top-K问题,就是求数据结合前K个最大的元素或者最小的元素,一般情况下数据量较大。比如:美团上的附近美食排行榜、年纪成绩排行榜等等。

       而对于Top-K问题,我们能想到的有三种不同的思路去解决。首先最简单直接的方式就是排序。但是如果需要处理的数据量非常大,排序就不太可取了。而另外两种方法就是使用堆:

  1. 用数据集合中前K个元素来建堆,若要取前K个最大的元素,则建小堆;若要取前K个最小的的元素,则建大堆
  2. 用剩余的N-K个元素依次与堆顶元素来比较,不满足则替换堆顶元素,最终堆中剩余的K个元素就是所求的前K个最小或者最大的元素。

二、不同解决思路实现:

①.排序法:

        排序法的思路很好理解,就是将所有的数据进行排序,再根据需求取值即可。过程中使用的排序方法就是向下调整,时间复杂度是O(nlogn):

//排序法:
Swap(int* a, int* b)
{int tmp = *a;*a = *b;*b = tmp;
}
void HeapSort(int* a, int n)
{for (int i = 1; i < n; i++){Adujustup(a, i);}while ((n-1) > 0){Swap(&a[0], &a[n - 1]);n--;Adujustdown(a, n-1, 0);}
}

        这种方法就相当于遍历所有的数据进行比较排序,因此会将会造成大量的内存消耗和使用,存在着较大的弊端。

②.直接建堆法:

        直接建堆法的作用原理为:建立一个大堆(时间复杂度O(logn)),然后取出堆顶元素并将其删除,然后调整堆,重复这个步骤K次。

void HeapSort(int* a, int n)
{for (int i = 1; i < n; i++){Adujustup(a, i);}for(int i=0;i<k;i++){printf("%d",HeapTop(a));HeapPop(a);}

        虽然这种算法有了一定程度的改进,但是仍然没有改变再内存中进行操作的本质,其操作方式仍然会造成大量内存的占用和消耗。

③.K堆法

        由于上述两种方法都是当n很大时,所占用的内存将会非常大,例如我们假设n为100亿,此时便有:1G=1024Mb=1024*1024Kb=1024*1024*1024Byte,需要使用内存将达到10byte。

        于是我们就采用另外一种建堆方式——K堆法:建一个大小为K的小堆。

为什么时小堆呢?

        因为小堆的堆顶是K的元素中最小的,而我每次只需要跟堆顶比较然后淘汰K个元素中最

小的一个,最后N-K比较完之后这K个元素就是TopK了。

void TestTopk(HP* p, int k)
{int* arr = (int*)malloc(sizeof(int) * k);int n = p->size;for (int i = 1; i < n; i++){SAdujustup(p->a, i);}for (int i = 0; i < k; i++){arr[i] = p->a[0];p->a[0] = p->a[p->size - 1];p->size--;n = p->size;for (int i = 1; i < n; i++){SAdujustup(p->a, i);}}for (int i = 1; i < k; i++){SAdujustup(arr, i);}for (int i = 0; i < k; i++){printf("%d ", arr[i]);}
}

总结:

        到这里,我们今天关于Topk问题的研究就全部结束了,难度不大,最主要是结合具体情况,选择最合适的方法建堆。

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

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

相关文章

RabbitMQ到底为什么要使用它?

导入 一个技术的衍生必然是为了解决现实出现的问题&#xff0c;在讲这个问题之前我们先了解一下传统开发中关于服务调用出现的问题&#xff08;痛点&#xff09;有哪些&#xff1f; 我们为什么要使用MQ&#xff1f; ①、同步——超时 在多服务体系架构中&#xff0c;必然存在…

Kyuubi的介绍优势(官网链接)

官网链接&#xff1a;https://kyuubi.apache.org/ Apache Kyuubi™ 是一个分布式多租户网关&#xff0c;用于在数据仓库和 Lakehouse 上提供无服务器 SQL。 Kyuubi 在各种现代计算框架&#xff08;例如 Apache Spark、 Flink、 Doris、 Hive和Trino等&#xff09;之上构建分布…

全志F1C200S嵌入式驱动开发(GPIO输出)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】 和v3s一样,f1c200s本身的外部引脚比较少。所以这个时候,不可避免地,很多引脚的功能就会重叠在一起。这种情况下,我们就要学会取舍了。比如说,如果是学习sd卡的时候,那么spi的…

MS1826 HDMI 四进四出多功能视频处理器

MS1826 是一款多功能视频处理器&#xff0c;包含 4 路独立 HDMI 音视频输入通道、4 路独立 HDMI 音视频输出通道以及四路独立可配置为输入或者输出的 SPDIF、I2S 音频信号。支持 4 个独立 的字库定制型 OSD&#xff1b;可处理隔行和逐行视频或者图形输入信号&#xff1b;有四…

CSS——基础知识及使用

CSS 是什么 CSS是层叠样式表 (Cascading Style Sheets)的简写.CSS 能够对网页中元素位置的排版进行像素级精确控制, 实现美化页面的效果. 能够做到页面的样式和结构分离。 基本语法规范 选择器 { 一条/N条声明 } 选择器决定针对谁修改 (找谁)声明决定修改啥. (干啥)声明的…

css3的新特性

动画效果 过渡 transition 鼠标放上去瞬间变大 过渡是变大的过程慢慢变化 第一个参数&#xff1a;对哪些值进行过渡。all为hover中所有&#xff0c;也可以指定属性 第二个参数&#xff1a;让动画过渡多长时间。要添加单位&#xff08;s秒&#xff09; 第三个参数&#xff1…

P5708 【深基2.习2】三角形面积

题目描述 一个三角形的三边长分别是 &#xfffd;a、&#xfffd;b、&#xfffd;c&#xff0c;那么它的面积为 &#xfffd;(&#xfffd;−&#xfffd;)(&#xfffd;−&#xfffd;)(&#xfffd;−&#xfffd;)p(p−a)(p−b)(p−c)​&#xff0c;其中 &#xfffd;12(&a…

D354周赛复盘:特殊元素平方和+数组最大美丽值(滑动窗口)+合法分割最小下标

文章目录 6889.特殊元素平方和思路完整版取模注意&#xff1a;不能对0取余/取模解答错误&#xff1a;本题的数组最后一个下标是nums[nums.size()] 6929.数组的最大美丽值&#xff08;排序滑动窗口&#xff09;思路1&#xff1a;排序滑动窗口注意点 6927. 合法分割的最小下标&am…

golang网络编程学习-TCP

golang网络编程学习-TCP 网络编程主要的内容是&#xff1a; 1.TCP网络编程 2.http服务 3.rpc服务 4.websocket服务 golang网络编程学习-TCP 一、TCP/IP TCP/IP是一种协议簇&#xff0c;它是网络通信的基础&#xff0c;是互联网的核心协议&#xff0c;负责数据在网络中的传输。它…

SpringBoot+actuator和admin-UI实现监控中心

使用SpringBoot很久了&#xff0c;但是很少使用到SpringBoot的查看和监控&#xff0c;将来八成也不会用到&#xff0c;万一有机会用到呢&#xff1f;所以记录一下以前学习SpringBootactuator和adminUI实现监控中心的方式 Springboot的版本2.0.x <parent><groupId>…

Spring学习记录---回顾反射机制

目录 10.回顾反射机制 10.1 分析方法四要素 //不使用反射机制调用这些方法 使用反射机制调用方法 代码&#xff1a; 运行结果&#xff1a; 10.4 假设你知道属性名 测试代码 运行结果 10.回顾反射机制 10.1 分析方法四要素 package com.dong.reflect;public class Som…

【java爬虫】将优惠券数据存入数据库排序查询

本文是在之前两篇文章的基础上进行写作的 (1条消息) 【java爬虫】使用selenium爬取优惠券_haohulala的博客-CSDN博客 (1条消息) 【java爬虫】使用selenium获取某宝联盟淘口令_haohulala的博客-CSDN博客 前两篇文章介绍了如何获取优惠券的基础信息&#xff0c;本文将获取到的…

Make:默认构建目标(终极目标)

相关文章 Make&#xff1a;目标&#xff08;Target&#xff09;构建的详细和依赖项的处理过程&#xff08;个人总结&#xff09; 默认情况下make命令的构建从第一个没有 . 前缀的目标&#xff08;target&#xff09;开始&#xff08;除非有 . 前缀的目标中有一个或更多 / &…

PyTorch 1.13简介

# 1.  PyTorch 1.13 据官方介绍&#xff0c;PyTorch 1.13 中包括了 BetterTransformer 的稳定版&#xff0c;且不再支持 CUDA 10.2 及 11.3&#xff0c;并完成了向 CUDA 11.6 及 11.7 的迁移。此外 Beta 版还增加了对 Apple M1 芯片及 functorch 的支持。 1.1 主要更新 Be…

php运算符的基本使用

$base 20; $height 10; $area $base * $height; 我用来将base与height相乘的* &#xff0c;就是乘法运算。 我们有相当多的运算符&#xff0c;让我们对主要的运算符做一个简单的总结。 首先&#xff0c;这里是算术运算符。,-,*,/ &#xff08;除法&#xff09;,% &#x…

C++第四讲

思维导图 仿照string类&#xff0c;实现myString类 /* ---------------------------------author&#xff1a;YoungZorncreated on 2023/7/19 19:20.--------------------------------- */ #include<iostream> #include<cstring>using namespace std;class myStri…

【Windows】查找占用端口的进程、结束进程

记录一下在windows环境下通过命令行窗口进行进程有关的几个操作。 1、查找占用端口的进程ID(PID)&#xff1a; netstat -ano|findstr 28087 假如PID为21812、根据PID找进程名称&#xff1a; tasklist | findstr 2181 发现是占用28087端口的进程为&#xff1a;java.exe。 3、…

【数据结构】时间复杂度---OJ练习题

目录 &#x1f334;时间复杂度练习 &#x1f4cc;面试题--->消失的数字 题目描述 题目链接&#xff1a;面试题 17.04. 消失的数字 &#x1f334;解题思路 &#x1f4cc;思路1&#xff1a; malloc函数用法 &#x1f4cc;思路2&#xff1a; &#x1f4cc;思路3&…

LeetCode(字节10日)-0714

648. 单词替换(中等) 思路&#xff1a;前缀树匹配 // 思路&#xff1a;前缀树匹配&#xff0c;成功返回前缀&#xff0c;失败返回 null&#xff0c;保留原来单词值 // 多个词根时使用最短词根&#xff0c;不需要 fail 指针 // string 处理使用 stringBuilder&#xff0c;避…

如何使用DiskPart命令行格式化分区?

想要格式化磁盘分区&#xff0c;您可以使用磁盘管理工具&#xff0c;或在Windows文件资源管理器中右键单击驱动器并选择“格式化”。如果您更想使用命令行来格式化磁盘&#xff0c;那么Windows自带的DiskPart将是首选。 DiskPart有很多优点&#xff0c;例如&#xff0c;如果您想…