首页 > 其他分享 >TopK的实现

TopK的实现

时间:2024-07-30 16:28:10浏览次数:8  
标签:10 arr parent 实现 filename int TopK child

在此前,已经介绍了向下调整算法,建堆以及堆排序的实现,这篇文章将实现TopK问题。

前提:从1000个数据中找出10个最小的,这里的实现用到了文件操作,现实中若是基数很大,不能直接在内存中保存,则要借助文件将数据保存,然后再提取数据进行比较。大概步骤如下:

1:生成1000个随机数,做为本次要排序的基数。

2:为了找10个最小的,即提取出10个数来建堆,建大堆(建大堆即这10个元素中最大的元素在堆顶,然后将剩下的元素依次提取,与堆顶比较,若是比堆顶小,则将堆顶替换为该数据,再进行调整,变为大堆,调整后堆顶数据还是新的10个数据中最大的,然后继续提取,比较,调整)。

3:遍历剩下的所有元素。

创建基础数据:

void CreatDate(char* filename, int N)
{
	FILE* fin = fopen(filename, "w");
	if (fin == NULL)
	{
		perror("CreatDate");
	}
	srand(time(NULL));
	int i = 0;
	while (i < N)
	{
		fprintf(fin,"%d\n",rand()%1000);
		i++;
	}
	fclose(fin);
}

这里是创建N个数据,rand()%1000将数据范围限制在0-999,rand()使用前要先调用srand()这样才能使每次生成的数据有随机行,不然每次生成的数据顺序都是一样的。

建堆:

void Swap(int* p1, int* p2)
{
	int tmp = *p1;
	*p1 = *p2;
	*p2 = tmp;
}

//大堆,找最小
void AdjustDown(int* arr, int parent, int K)
{
	int child = 2 * parent + 1;
	while (child < K)
	{
		if (child + 1 < K && arr[child + 1] > arr[child])
		{
			child = child + 1;
		}
		if (arr[child] > arr[parent])
		{
			Swap(&arr[child], &arr[parent]);
			parent = child;
			child = 2 * parent + 1;
		}
		else
		{
			break;
		}
	}
}

TopK实现:

void PrintTopK(char* filename, int K)
{
	FILE* fout = fopen(filename, "r");
	if (fout == NULL)
	{
		perror("PrintTopK");
	}
	//读取前k个数,
	int* arr = (int*)malloc(sizeof(int) * K);
	if (arr == NULL)
	{
		exit(-1);
	}
	int i = 0;
	for (i = 0; i < K; i++)
	{
		fscanf(fout, "%d\n", &arr[i]);
	}
	//建堆
	for (i = (K-1-1)/2; i >= 0; i--)
	{
		AdjustDown(arr,i,K);
	}
	//遍历剩下的元素,与堆顶元素比较,比堆顶小则替换堆顶,
	int num = 0;
	while (fscanf(fout, "%d\n", &num) != EOF)
	{
		if (arr[0] > num)
		{
			arr[0] = num;
			AdjustDown(arr, 0, K);
		}
	}
	//打印最后的k个数据
	for (i = 0; i < K; i++)
	{
		printf("%d ", arr[i]);
	}
	fclose(fout);
	free(arr);
	arr = NULL;
}

主函数:

int main()
{
	char* filename = "Date.txt";
	int N = 1000;
	int K = 10;
	//CreatDate(filename, N);
	PrintTopK(filename, K);
	return 0;
}

标签:10,arr,parent,实现,filename,int,TopK,child
From: https://blog.csdn.net/guaiguaiyalj/article/details/140796122

相关文章

  • OpenCV实现图搜图简单案例
    一、概述使用OpenCV实现一个简单的图搜索的小功能特点:暴力匹配实现原理:1.将图片集合生成特征描述,并存入文件2.加载目标图像,并生成图像特征描述3.加载图像特征描述文件列表4.图像特征描述和集合中的特征描述列表进行匹配......
  • 如何实现像素洗牌
    在tensorflow中,有一种像素洗牌方法称为depth_to_space它的作用如下:假设我们有一个维度为(4,4,4)的图像(数组)。上面的方法会打乱这个数组的值,以便我们按照下图所示的方式获得一个大小为(16,16,1)的数组:我现在尝试了几个小时,使用numpy重新创建......
  • javaweb面向切面aop编程-实现自定义填充
    实现自定义填充注解@AutoFill创建annotation包,编写注解类点击查看代码/***自定义注解,用于标识某个方法需要进行功能字段自动填充处理*/@Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)public@interfaceAutoFill{//数据库操作类型:UPDATEINSE......
  • 利用结构体数组 实现学生信息管理系统(模块化编程)
    核心功能(必须实现):                        新增信息查询信息修改信息删除信息 信息排序扩展功能:                        按字符串索引, 插入信息 提升功能:                        账号注......
  • 在Java中利用GeoHash实现高效的‘附近xxx‘功能
    GeoHash的介绍GeoHash是一种高效的地理编码系统,它通过将地球表面划分为网格并用字母数字组合的字符串来表示每个区域。这种编码方法将二维的经纬度坐标转换为一维的字符串,使得地理位置的存储和检索变得更加简单。GeoHash的核心原理是将经纬度坐标转换为二进制,然后交替取位......
  • Docker中使用自定义网络方式实现Redis集群部署与测试流程
    场景Docker中Docker网络-理解Docker0与自定义网络的使用示例:https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/140788458参考上面的流程实现自定义网络的实现。下面记录其应用实例,使用Docker的自定义网络实现redis集群部署。注:博客:https://blog.csdn.net/badao_......
  • 比传统PID算法更容易实现和调试的增量调速法
    当你接到一个控制任务,比如需要控制电机的转速,并支持动态快速调整转速,电机的转速可以实时获取。然后开始网上一顿搜索,搜索结果大致如下所述。在自动控制领域中,PID控制算法是一种非常常见且有效的控制算法,用于实现闭环控制系统中的精确控制。PID控制器由三个组成部分构成:比例......
  • EasyExcel数据导出实现、动态表头生成、SpringBoot3框架
    1、引入EasyExcel依赖<dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>3.3.2</version></dependency>2、定义ExcelModel表单模型publicclassExcelMod......
  • 跨链实现与原理
    跨链的实现和原理常见的有哪些跨链技术旨在解决不同区块链网络之间的互操作性问题,使得这些区块链可以相互通信、交换价值和数据。以下是几种常见的跨链实现和原理:1.中继(Relays)中继是一种跨链技术,通过一个中继合约来监听一个区块链上的事件,并将这些事件转发到另一个区块链上。......
  • 如何注释可以实现为属性的属性?
    我试图让mypy对我的类型注释感到满意。这是一个最小的例子:classFooInterface:x:intclassFooWithAttribute(FooInterface):x:int=0classFooWithProperty(FooInterface):@propertydefx(self)->int:return0以我人类的理解,一......