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

news2025/2/27 2:01:21

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.coloradmin.cn/o/1528593.html

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

相关文章

词令微信小程序怎么添加到我的小程序?

微信小程序怎么添加到我的小程序&#xff1f; 1、找到并打开要添加的小程序&#xff1b; 2、打开小程序后&#xff0c;点击右上角的「…」 3、点击后底部弹窗更多选项&#xff0c;请找到并点击「添加到我的小程序」&#xff1b; 4、添加成功后&#xff0c;就可以在首页下拉我的…

代码随想录算法训练营第二十七天 |131.分割回文串,一些思考

实际上&#xff0c;分割子集问题也是组合问题 &#xff08;图源代码随想录网站&#xff09; 一个套路&#xff0c;也就是说&#xff0c;每次递归函数参数列表传入start的时候&#xff0c;选中的元素相当于是在最后面划了一条分割线 回文子串的判断剪枝操作就很简单了&#xf…

AIGC元年大模型发展现状手册

零、AIGC大模型概览 AIGC大模型在人工智能领域取得了重大突破&#xff0c;涵盖了LLM大模型、多模态大模型、图像生成大模型以及视频生成大模型等四种类型。这些模型不仅拓宽了人工智能的应用范围&#xff0c;也提升了其处理复杂任务的能力。a.) LLM大模型通过深度学习和自然语…

什么是闭包?闭包的优缺点?闭包的应用场景?

什么是闭包&#xff1f; 闭包是指有权访问另外一个函数作用域中的变量的函数。 闭包形成的必要条件&#xff1a; 函数嵌套内部函数使用外部函数的变量内部函数作为返回值 举个栗子&#xff1a;实现每隔1s递增打印数字 使用闭包实现 for(var i1; i<5; i) {(function(i) {se…

Cointelegraph 策略主管 JASON CHOI确认出席Hack.Summit() 2024区块链开发者大会

随着区块链技术的蓬勃发展和广泛应用&#xff0c;一场备受瞩目的盛会即将拉开帷幕。Hack.Summit() 2024区块链开发者大会&#xff0c;由Hack VC主办&#xff0c;AltLayer和Berachain协办&#xff0c;Solana、The Graph、Blockchain Academy、ScalingX、0G、SNZ和数码港等机构的…

Python——模块

自定义模块 module_exercise.py文件 data 100 def func01():print("func01执行喽") class Myclass:def func02(self):print("func02执行喽")classmethoddef func03(cls):print("func03执行喽") exercise.py文件 # 调用方法1&#xff1a;&quo…

Unity2D实现鼠标拖动物体移动(简单好抄)

1.新建脚本&#xff0c;并将脚本拖到你想要拖动的物体上即可 using System.Collections; using System.Collections.Generic; using Unity.VisualScripting; using UnityEngine;public class text : MonoBehaviour {private Vector3 offset;public int x 1;void OnMouseDown(…

入门:vue使用Echarts绘制地图的步骤

匠心接单中...8年前端开发和UI设计接单经验&#xff0c;完工项目1000&#xff0c;持续为友友们分享有价值、有见地的干货观点&#xff0c;有业务需求的老铁&#xff0c;欢迎关注发私信。 安装echarts和echarts-map插件 npm install echarts --save npm install echarts-map --…

深入理解mysql 从入门到精通

1. MySQL结构 由下图可得MySQL的体系构架划分为&#xff1a;1.网络接入层 2.服务层 3.存储引擎层 4.文件系统层 1.网络接入层 提供了应用程序接入MySQL服务的接口。客户端与服务端建立连接&#xff0c;客户端发送SQL到服务端&#xff0c;Java中通过JDBC来实现连接数据库。 …

YOLOV5 部署:基于web网页的目标检测(本地、云端均可)

1、前言 YOLOV5推理的代码很复杂,大多数都是要通过命令行传入参数进行推理,不仅麻烦而且小白不便使用。 本章介绍的web推理,仅仅需要十几行代码就能实现本地推理,并且只需要更改单个参数就可以很方便的部署云端,外网也可以随时的使用 之前文章介绍了QT的可视化推理界面,…

代码随想录day25(2)二叉树:验证二叉搜索树(leetcode98)

题目要求&#xff1a;给定一个二叉树&#xff0c;判断其是否是一个有效的二叉搜索树。 思路&#xff1a;首先对于二叉搜索树&#xff0c;它的中序遍历是有序的。最简单的想法就是将二叉搜索树转成一个数组&#xff0c;验证数组是否有序就可以&#xff08;二叉搜索树中没有重复…

ResNet模型结构

一、ResNet网路模型 ResNet模型由堆叠残差结构所得到 ResNet34 实线和虚线的残差结构不同&#xff1a; 虚线是conv2_x&#xff0c;conv3_x&#xff0c;conv4_x&#xff0c;conv4_x&#xff0c;第一层的残差结构。要将上一层的残差特征矩阵的尺寸和深度调整为当前层所需要的 二…

Aigtek超声功率放大器产品介绍

超声功率放大器是一种特殊类型的功率放大器&#xff0c;专门用于增强和放大超声信号的功率。它在医疗、工业和科学领域中得到广泛应用。 一、超声功率放大器的基本概述 超声功率放大器是一种能够将低功率超声信号放大到更高功率水平的设备。它是超声系统的关键组成部分&#xf…

OPPO 后端二面,凉凉。。。

美众议院通过 TikTok 法案 之前我们讲了 老美要求字节跳动在 165 天内剥离短视频应用 TikTok&#xff0c;当时的最新进度是 TikTok 给 1.7 亿美国用户发弹窗&#xff0c;发动用户群众给国会打电话进行抗议。 但显然这点力度的抗议并不会造成什么实质影响。 昨晚&#xff0c;美国…

门店运营三大核心揭秘:打造高效盈利模式的关键

在当今竞争激烈的商业环境中&#xff0c;开设一家成功的实体店并非易事。对于那些渴望投身实体店创业或已经在创业道路上的人来说&#xff0c;了解如何打造高效盈利模式是至关重要的。作为一名经营鲜奶吧5年时间的创业者&#xff0c;我将持续在网上分享开店的干货和见解&#x…

MySQL最实用面试题(2024-3-14持续更新中)

MySQL篇面试题 一、介绍 ​ 这是由小龙同学自己总结领悟的mysql面试题的解析&#xff0c;也是面试宝典 二、题目 1.数据库三大范式&#xff1a; –作用&#xff1a; ​ 使表结构清晰&#xff0c;减少数据冗余&#xff08;简单讲就是重复&#xff09;&#xff0c;提高查询…

Kafka:分布式消息队列

1. 简介 介绍 Kafka 的概述、优势和劣势&#xff0c;以及应用场景。 2. 基本概念 2.1 架构 一个典型的 Kafka 体系架构包括若干 Producer、若干Broker、若干 Consumer&#xff0c;以及一个ZooKeeper集群。 ZooKeeper是Kafka用来负责集群元数据的管理、控制器的选举等操作的…

基于Spring Boot的社区便民服务管理系统的设计与实现

摘 要 二十一世纪我们的社会进入了信息时代&#xff0c;信息管理系统的建立&#xff0c;大大提高了人们信息化水平。传统的管理方式对时间、地点的限制太多&#xff0c;而在线管理系统刚好能满足这些需求&#xff0c;在线管理系统突破了传统管理方式的局限性。于是本文针对这一…

js逆向-某东cfe滑块逆向分析

声明 本文仅供学习参考&#xff0c;如有侵权可私信本人删除&#xff0c;请勿用于其他途径&#xff0c;违者后果自负&#xff01; 如果觉得文章对你有所帮助&#xff0c;可以给博主点击关注和收藏哦&#xff01; 分析 网址&#xff1a; aHR0cHM6Ly9jZmUubS5qZC5jb20vcHJpdmF…

鸿蒙Harmony应用开发—ArkTS声明式开发(容器组件:Panel)

可滑动面板&#xff0c;提供一种轻量的内容展示窗口&#xff0c;方便在不同尺寸中切换。 说明&#xff1a; 该组件从API Version 7开始支持。后续版本如有新增内容&#xff0c;则采用上角标单独标记该内容的起始版本。 子组件 可以包含子组件。 说明&#xff1a; 子组件类型&a…