C语言数据结构基础——二叉树学习笔记(二)topk问题

1.top-k问题

1.1思路分析

    TOP-K 问题:即求数据结合中前 K 个最大的元素或者最小的元素,一般情况下数据量都比较大
      比如:专业前 10 名、世界 500 强、富豪榜、游戏中前 100 的活跃玩家等。
对于 Top-K 问题,能想到的最简单直接的方式就是排序,但是:如果数据量非常大,排序就不太可取了 ( 可能 数据都不能一下子全部加载到内存中)

     在我们之前的解决方法中,堆的物理结构都是数组,假如我们要在100亿个人中找出前十个有钱的人,暂且不论每个人的数据是结构体,就把每个人的数据看做一个整数。

100亿个整数有400亿个字节。我们把1000 000 000看做(1024^3),也就是十亿字节是一个g,四百亿字节就是40个g,一个简单的找前十有钱人功能就需要运行内存为40个g的电脑,空间需求未免也太大了。

                                                   

我们以共有N个数据,找前k个举例 (N远大于k)

思路一:

     假如电脑运行内存足够大,我们建立出了这样一个大堆,依据上文C语言数据结构基础笔记——树、二叉树简介-CSDN博客中的讲解,用向上遍历的向下调整算法建大堆,时间复杂度是O(n),再pop k次,由于每次pop都会经历向下调整算法,故总复杂度应该为N+klogN

思路二:

建立一个由k个树构成的小堆,保证根部是先存在堆中最小的数据,然后遍历数据,遇到比根更小的数据就交换并且实行向下调整算法,时间复杂度应N-k+k+Nlogk(+k是将k个数据建堆的消耗,N-k是遍历剩下元素的消耗)

对比两种思路,时间复杂度接近,但是思路二的空间复杂度为O(1),思路二的空间复杂度为O(N)

因此,思路二是最佳选择。

总结就是:找最大的k个用小堆,找最小的k个用大堆(这样才能挑出最不符合条件的来被替换掉)

1.2代码实现

我们以在文件中读取和输入为背景,实现将文件中的top_k个数据给输出

首先,作为程序员,一定是不能去手动给文件中输入一万个随机值作为测试用例的。

我们封装一段函数来创造样本,输入到本地的data.txt中去

void CreatFile(void) {const char* filename = "data.txt";int number = 100;FILE* pf = fopen(filename, "w");//初始化时间种子srand((unsigned int)time(NULL));for (int i = 0; i < number; i++) {fprintf(pf, "%d\n", rand());}fclose(pf);
}

先只创造100个即可

(创造测试用例也有许多技巧,在之后的测试中会有体现) 


创造好样本后,我们在topk函数中建k个数的小堆,运用文件读写的方法先写入K个数据,再依次遍历并进行交换

void topk(int k,int number) {//建立数组空间HeapDataType* minheap = (HeapDataType*)malloc(sizeof(HeapDataType) * k);if (minheap == NULL) {perror("malloc fail!");exit(1);}//打开文件,将k个数据先放入数组const char* filename = "data.txt";FILE* pf = fopen(filename, "r");for (int i = 0; i < k; i++) {fscanf(pf, "%d", &minheap[i]);}//使用向上遍历的向下调整算法建小堆for (int i = (k - 1 - 1) / 2; i >= 0; i--) {AdjustDown(minheap, k, i);}//此时k个数据的小堆已经建好,开始遍历数组for (int i = 1; i <= number-k ; i++) {int x = 0;fscanf(pf, "%d", &x);if (x > minheap[0]) {Swap(&x, &minheap[0]);AdjustDown(minheap, k, 0);}}fclose(pf);for (int i = 0; i < k; i++) {printf("%d ", minheap[i]);}
}int main() {int k = 0;int number = 0;printf("请输入k值和数据总量:\n");scanf("%d,%d", &k,&number);// CreatFile(number);topk(k,number);return 0;
}

 我们再将样本调小,k输入5,number输入10

注意,输入数据时两个数据之间需要是英文的逗号,中文的逗号会被视作两个字符而导致number不能正确读入

由此可见,我们成功的完成了任务,输出了10个数中最大的五个。

可是有没有可能,我们的代码在数据量如此小的时候能跑过,当数据达到100万时会挂掉呢?

我们将k调到10,number调到100万,新的问题又出现了,我怎么才知道输出的就是最大的10个呢,100万个数据没法使用肉眼比较。

测试小技巧

控制用例范围,

//将生成随机数的语句调整为
fprintf(pf, "%d\n", (rand() + i)%1000000);

再在文件中手动设置出最大的几个样本,用于检测.(随机加入了11111和23456或者123123等)

                                              


第一次使用creat函数,第二次使用topk函数 ,这样更便于调试

topk问题成功解决。

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

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

相关文章

Gradle v8.5 笔记 - 从入门到进阶(基于 Kotlin DSL)

目录 一、前置说明 二、Gradle 启动&#xff01; 2.1、安装 2.2、初始化项目 2.3、gradle 项目目录介绍 2.4、Gradle 项目下载慢&#xff1f;&#xff08;万能解决办法&#xff09; 2.5、Gradle 常用命令 2.6、项目构建流程 2.7、设置文件&#xff08;settings.gradle.…

什么是web组态?Web组态软件哪个好用?

随着工业4.0的到来&#xff0c;物联网、大数据、人工智能等技术的融合应用&#xff0c;使得工业领域正在经历一场深刻的变革。在这个过程中&#xff0c;Web组态技术以其独特的优势&#xff0c;正在逐渐受到越来越多企业的关注和认可。那么&#xff0c;什么是Web组态&#xff1f…

快速从0-1完成聊天室开发——环信ChatroomUIKit功能详解

聊天室是当下泛娱乐社交应用中最经典的玩法&#xff0c;通过调用环信的 IM SDK 接口&#xff0c;可以快速创建聊天室。如果想根据自己业务需求对聊天室应用的 UI界面、弹幕消息、礼物打赏系统等进行自定义设计&#xff0c;最高效的方式则是使用环信的 ChatroomUIKit 。 文档地址…

打开Railway神奇大门:Railway免费注册部署全面教程

&#x1f9d9;‍♂️ 诸位好&#xff0c;吾乃斜杠君&#xff0c;编程界之翘楚&#xff0c;代码之大师。算法如流水&#xff0c;逻辑如棋局。 &#x1f4dc; 吾之笔记&#xff0c;内含诸般技术之秘诀。吾欲以此笔记&#xff0c;传授编程之道&#xff0c;助汝解技术难题。 &#…

JavaScript初学心得

JavaScript JavaScript原名是livescript&#xff0c;是由美国网景开发的一种用于对网页操作的脚本语言 网页操作&#xff08;图片切换&#xff09; 脚本语言&#xff08;不需要编译 sql,html,css,javascript,由某种解释器直接可以运行&#xff09; livescript也是面向对象的…

外键约束

目录 外键约束 对数据表进行初期设计&#xff0c;暂时不使用外键 验证限制三 验证级联删除 设置级联更新 Oracle从入门到总裁:​​​​​​https://blog.csdn.net/weixin_67859959/article/details/135209645 外键约束 外键约束主要是在父子表关系中体现的一种约束操作。…

代码随想录算法训练营day28 | 回溯算法之93.复原IP地址 78.子集 90.子集II

三刷day28 93.复原IP地址判断子串是否合法 78.子集回溯三部曲 90.子集II 93.复原IP地址 题目链接 解题思路&#xff1a; 切割问题就可以使用回溯搜索法把所有可能性搜出来 回溯三部曲 递归参数 startIndex一定是需要的&#xff0c;因为不能重复分割&#xff0c;记录下一层递…

windows取证

Windows事件日志分析 使用Windows事件日志查看器&#xff0c;打开实验文档“security01.evtx”。按“日期和时间”对日志进行分组统计&#xff1b;按“事件ID”对日志进行分组统计&#xff1a; 问题&#xff1a;日志中是否有用户登录失败的记录。如果有&#xff0c;请按“登录…

AI智能客服的数据训练流程

实现智能客服的数据训练流程可以分为几个主要步骤&#xff0c;包括数据准备、模型选择、模型训练和评估。以下是一个基本的数据训练流程&#xff0c;希望对大家有所帮助。北京木奇移动技术有限公司&#xff0c;专业的软件外包开发公司&#xff0c;欢迎交流合作。 1.数据准备&am…

1-postgresql数据库高可用脚本详解

问题&#xff1a; pgrep -f postgres > /dev/null && echo 0 || pkill keepalived 这是什么意思 建议换成 pgrep -f postmaster > /dev/null && echo 0 || pkill keepalived 回答 这条命令是一个复合命令&#xff0c;包含条件执行和重定向的元素。让我们…

三、转移字符、字符串、bool类型和eval函数

一、转义字符 \n&#xff1a;换行符 \t&#xff1a;制表符 \&#xff1a;单引号 \"&#xff1a;双引号 \\&#xff1a;反斜杠 a人生无常 b我用python print(ab) print(f"{a}\n{b}") print(f"{a}\t{b}") print(fr"{a}\t{b}") 在打印字…

const,static深度总结——c++穿透式分析

前言&#xff1b;c类和对象的知识点中除了几种默认函数&#xff0c; 比较重要的还有使用const和static修饰成员相关知识点。const在c中特性很简单。 但是在使用中&#xff0c; 比较容易疏忽大意出现问题。 static特性也很简单&#xff0c; 但是比起const来要直接的多。 在使用中…

LAMP架构部署--yum安装方式

这里写目录标题 LAMP架构部署web服务器工作流程web工作流程 yum安装方式安装软件包配置apache启用代理模块 配置虚拟主机配置php验证 LAMP架构部署 web服务器工作流程 web服务器的资源分为两种&#xff0c;静态资源和动态资源 静态资源就是指静态内容&#xff0c;客户端从服…

如何选择合适的奶瓶?五大超实用选购技巧,新手宝妈必看

奶瓶什么品牌好&#xff1f;奶瓶是每个新生宝宝都需要用到的辅喂产品&#xff0c;然而市场上许多网红品牌为了赚快钱&#xff0c;往往凭借外观设计、性价比和广告营销来吸引消费者。这些品牌由于缺乏专业技术&#xff0c;往往没有对选材用料和安全性进一步的优化&#xff0c;从…

MNN Session::resize 之流水线编码(五)

系列文章目录 MNN createFromBuffer&#xff08;一&#xff09; MNN createRuntime&#xff08;二&#xff09; MNN createSession 之 Schedule&#xff08;三&#xff09; MNN createSession 之创建流水线后端&#xff08;四&#xff09; MNN Session::resize 之流水线编码&am…

【LeetCode: 173. 二叉搜索树迭代器 + dfs + 二叉搜索树】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

电脑数据安全新利器:自动备份文件的重要性与实用方案

一、数据安全的守护神&#xff1a;自动备份文件的重要性 在数字化时代&#xff0c;电脑中的文件承载着我们的工作成果、个人回忆以及众多重要信息。然而&#xff0c;数据丢失的风险无处不在&#xff0c;无论是硬件故障、软件崩溃&#xff0c;还是恶意软件的攻击&#xff0c;都…

Python计算机二级选择易错题(一)

题目来源&#xff1a;python计算机二级真题&#xff08;选择题&#xff09; - 知乎 选择题第08&#xff0c;09套

力扣刷题Days22-49.字母异位词(js)

目录 1&#xff0c;题目 2&#xff0c;代码 2.1利用数组排序作为键名 2.2计数实现 3&#xff0c;学习与总结 1&#xff0c;题目 给你一个字符串数组&#xff0c;请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。 字母异位词 是由重新排列源单词的所有字母得到…

虚拟化技术

前言 大家好我是jiantaoyab&#xff0c;这是我所总结作为学习的笔记第十八篇&#xff0c;在这里分享给大家&#xff0c;这篇文章讲虚拟技术就是大家平时用到的云服务器是什么。 虚拟机技术变迁 虚拟机&#xff08;Virtual Machine&#xff09;技术&#xff0c;其实就是指在现…