【数据结构】 堆排序与TopK问题详解

在学习完堆的创建后,就轮到了标题的两个问题
这两个问题在实际生活中会有比较强的实际问题解决能力
先分别解释一下

  • 堆排序:
    运用堆的思想进行排序,时间复杂度为O(NlogN)
  • TopK:
    从一大堆数据中选择K个最大或最小的数据,我们简称tTopK

堆的创建,关于堆的详情请点击。

目录

  • 堆排序:
    • 思想:
    • 代码实现:
    • 源代码:
  • TopK:
  • 思想:
    • 代码实现:
    • 源代码:

堆排序:

思想:

假设我们有一个小堆为N个数,先在要对其排序,那么这个小堆适合什么排序呢?

答案是降序

绝大部分同学可能都会认为是升序,
因为最上边的元素是最小的,我们将第一个固定住,在对其后边N-1个再次进行建堆,就可以完美得到一个升序的数组,
注意:

但是我们忽略了建堆的时间复杂度为O(lNogN),对N个数进行建堆,比冒泡排序有过之而无不及,所以我们不会去用这样一个华而不实的方法

所以我们小堆其实更适合降序,将建堆之后的第一个元素与数组末尾进行交换,再对这N-1个数进行向下调整算法,每调整一次时间复杂度为O(N),以此类推,再将第一个与倒数第二个交换…

代码实现:

我们既然进行排序,就要有一个待排序的数组,我们将数组传给堆排序,同样,当然也需要知道数组个数

	int arr[] = { 5,7,3,9,1,2,6,0 };HeapSort(arr, sizeof(arr) / sizeof(arr[0]));

然后我们就可以对这个数组进行建堆了,你的升降序也是根据你建的堆来进行的,要仔细区分
对于建堆,我们有两种方法

自上而下建堆:
这也是我们最容易想到的一种
利用循环将数组变成小堆

	for (int child = 0; child < size; child++){AdjustUp(arr, child);}

自下而上建堆:
这是我们推荐的一种,因为他的时间复杂度小于上一种方式(从最后一个叶子节点的父节点开始,少了最后一层,而最后一层接近N/2个节点),同时,他只会用到向下调整算法,在进行排序时也只会用到向下算法,故很适合我们使用

	int parent = (size - 1 - 1) / 2;while (parent){AdjustDown(arr, size, parent);parent--;}AdjustDown(arr, size, parent);

排序代码:

	//因为是小堆,排序降序int child = size - 1;for (int i = child; i > 0; i--){Swap(&arr[0], &arr[i]);AdjustDown(arr, i, 0);}for (int i = 0; i < size; i++){printf("%d ", arr[i]);}

源代码:

heap.cheap.h我们用到的依然是开头链接处的代码,这里我们直接引用他们

void HeapSort(int* arr, int size)
{//建堆:向下与向上向下//for (int child = 0; child < size; child++)//{//	AdjustUp(arr, child);//}//向上int parent = (size - 1 - 1) / 2;while (parent){AdjustDown(arr, size, parent);parent--;}AdjustDown(arr, size, parent);//因为是小堆,排序降序int child = size - 1;for (int i = child; i > 0; i--){Swap(&arr[0], &arr[i]);AdjustDown(arr, i, 0);}for (int i = 0; i < size; i++){printf("%d ", arr[i]);}
}int main()
{int arr[] = { 5,7,3,9,1,2,6,0 };HeapSort(arr, sizeof(arr) / sizeof(arr[0]));return 0;
}

TopK:

思想:

关于TopK我们有两种实现方法:

  1. N个数据进行建堆,在依次Pop掉堆顶,得到K个最大或最小的数据,但这种方式显然代价太大,且如果N太大,malloc会开辟不出来这么多数据的数组
  2. 我们先建一个K个数的堆,假设为小堆,那么此时还是问同学们一个问题,小堆适合选出最大的还是最小的呢?
    解:
    答案是最大的,
    因为我们在建好一个小堆后,需要拿堆顶的元素与N个数据中剩下的元素比较,又因为我们是小堆,所以当一个元素大于栈顶元素时,那个元素就会进入堆,我们进行向下排序,那个元素就会下沉,直到选出K个最大的数据,
    如果建立大堆的话,假设堆顶是K个数中最大的数据,就会挡在前边,另外几个次大的数据就会入不了堆,造成错误

代码实现:

首先创建一个文件,里面有很多的数据

void CreatData()
{FILE* fin = fopen("pata.txt", "w");if (fin == NULL){perror("fopen error");return;}//write datasrand(time(NULL));for (int i = 0; i < 10000000; i++){int x = (rand() + i) % 10000000;fprintf(fin, "%d\n", x);}fclose(fin);
}

注意:
创建完文件后我们要进入文件,改变几个数值(改变为超过取模的数字,这样我们就可以验证我们的代码准确性在这里插入图片描述
创建一个大小为K的堆

FILE* fout = fopen(filename, "r");if (fout == NULL){perror("fopen fail");return;}// 建一个k个数小堆int* minheap = (int*)malloc(sizeof(int) * k);if (minheap == NULL){perror("malloc error");return;}

将大数据中的前N个放入堆中

	// 读取前k个,建小堆for (int i = 0; i < k; i++){fscanf(fout, "%d", &minheap[i]);AdjustUp(minheap, i);}

依次读取,直到读取完毕并打印数据

	int x = 0;while (fscanf(fout, "%d", &x) != EOF){if (x > minheap[0]){minheap[0] = x;AdjustDown(minheap, k, 0);}}for (int i = 0; i < k; i++){printf("%d ", minheap[i]);}printf("\n");free(minheap);fclose(fout);

源代码:

void CreatData()
{FILE* fin = fopen("pata.txt", "w");if (fin == NULL){perror("fopen error");return;}//write datasrand(time(NULL));for (int i = 0; i < 10000000; i++){int x = (rand() + i) % 10000000;fprintf(fin, "%d\n", x);}fclose(fin);
}void TopK(char* filename, int k)
{FILE* fout = fopen(filename, "r");if (fout == NULL){perror("fopen fail");return;}// 建一个k个数小堆int* minheap = (int*)malloc(sizeof(int) * k);if (minheap == NULL){perror("malloc error");return;}// 读取前k个,建小堆for (int i = 0; i < k; i++){fscanf(fout, "%d", &minheap[i]);AdjustUp(minheap, i);}int x = 0;while (fscanf(fout, "%d", &x) != EOF){if (x > minheap[0]){minheap[0] = x;AdjustDown(minheap, k, 0);}}for (int i = 0; i < k; i++){printf("%d ", minheap[i]);}printf("\n");free(minheap);fclose(fout);
}int main()
{
//粘贴时注意先将创建数据的函数放出来,单独修改后再TopK//CreatData();TopK("data.txt", 5);return 0;
}

有问题及时询问博主,25小时高强度冲浪

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

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

相关文章

鸿蒙开发学习——应用程序框架

文章目录 UIAbility的生命周期Create状态WindowStageCreateForeground和Background前后台展示控制onWindowStageDestroyDestory 总结 UIAbility的生命周期 感觉这里他讲的不清晰&#xff0c;UIAbility的4个声明周期是Create、Foreground&#xff08;桌面展示&#xff09;、Back…

IOS/安卓+charles实现抓包(主要解决证书网站无法打开问题)

安装 官网下载 https://www.charlesproxy.com/latest-release/download.do 安装charles文档 流程 上述链接解决下图问题 使用介绍 Charles介绍 上述链接看一至三即可&#xff0c;了解首页各个按钮的作用 charles全面使用教程及常见功能详解&#xff08;较详细&#xff09…

计算机视觉(OpenCV+TensorFlow)

计算机视觉&#xff08;OpenCVTensorFlow&#xff09; 文章目录 计算机视觉&#xff08;OpenCVTensorFlow&#xff09;前言3.图像金字塔3.1 高斯金字塔3.2 拉普拉斯金字塔 4.图像轮廓图像边缘和图像轮廓的区别检测图像绘制边缘 5.轮廓近似外接矩形外接圆 6. 模板匹配6.1 什么是…

Windows安装Mysql Workbench及常用操作

Mysql Workbench是mysql自带的可视化操作界面&#xff0c;功能是强大的&#xff0c;但界面和navicat比&#xff0c;就是觉得别扭&#xff0c;但其实用惯了也还好&#xff0c;各有特色吧。这里记录一下常用的操作。 官方手册&#xff1a;MySQL Workbench 一、安装 1. 下载 官方…

一、服务器准备

本案例使用VMware Workstation Pro虚拟机创建虚拟服务器来搭建Linux服务器集群&#xff0c;所用软件及版本如下&#xff1a; Centos7.7-64bit 1、三台虚拟机创建 第一种方式&#xff1a;通过iso镜像文件来进行安装(不推荐) 第二种方式&#xff1a;直接复制安装好的虚拟机文…

golang 函数选项模式

一 什么是函数选项模式 函数选项模式允许你使用接受零个或多个函数作为参数的可变构造函数来构建复杂结构。我们将这些函数称为选项&#xff0c;由此得名函数选项模式。 例子&#xff1a; 有业务实体Animal结构体&#xff0c;构造函数NewAnimal&#xff08;&#xff09;&…

:deep(){} 样式穿透不生效问题解决方案

在我们写vue的项目的时候&#xff0c;可能会遇到这种情况&#xff0c;父子组件&#xff0c;在父组件中使用了样式穿透给子组件的类添加样式&#xff0c;结果失败了。比如下面这种情况。 父组件 <template><p>我是父组件</p><Son /> </template>…

【深度优先】LeetCode1932:合并多棵二叉搜索树

作者推荐 动态规划LeetCode2552&#xff1a;优化了6版的1324模式 题目 给你 n 个 二叉搜索树的根节点 &#xff0c;存储在数组 trees 中&#xff08;下标从 0 开始&#xff09;&#xff0c;对应 n 棵不同的二叉搜索树。trees 中的每棵二叉搜索树 最多有 3 个节点 &#xff0…

HarmonyOS4.0 ArkUI组件

目录 简介 搭建开发环境 ArkUI基础组件 Image组件 Text组件 TextInput Button Slider 简介 HarmonyOS 4.0的ArkUI组件是一套UI开发框架&#xff0c;提供开发者进行应用UI开发时所必须的能力。在ArkUI中&#xff0c;组件是界面搭建与显示的最小单位&#xff0c;开发者通过…

Normalizing Kalman Filters for Multivariate Time Series Analysis

l l l means latent state&#xff0c;LGM means ‘linear Gaussian state space models’ 辅助信息 作者未提供代码

pip包管理工具

pip 是 Python 包管理工具&#xff0c;该工具提供了对Python包的查找、下载、安装、卸载的功能。 Python 2.7.9 或 Python 3.4 以上版本的python都自带 pip 工具 1. 配置pip国内镜像 pip安装的包都存在于外国的服务器上&#xff0c;速度会非常慢&#xff0c;可以给pip配置国内…

优彩云采集器最新版免费下载,优彩云采集器免费

随着网络时代的发展&#xff0c;SEO&#xff08;Search Engine Optimization&#xff0c;搜索引擎优化&#xff09;已经成为网站推广和营销的关键一环。在SEO的世界里&#xff0c;原创内容的重要性愈发凸显。想要做到每天更新大量原创文章&#xff0c;并不是一件轻松的事情。优…

排序算法:n个0~1000之间的整数,将他们从大到小排序

上榜理由&#xff1a; 如果没见过这种排序题&#xff0c;可能首先想到的就是常用的排序算法&#xff0c;比如快速排序&#xff0c;归并排序&#xff0c;那如果输入的n足够大&#xff0c;时间复杂度肯定比较高。其实题目0-1000的范围是一个题眼&#xff0c;所以一定有更优的排序…

国内哪个超声波清洗机品牌比较好?质量好超声波清洗机总结

近年来超声波清洗机可以说是非常火爆&#xff0c;可以清洗化妆刷、眼镜、牙套等等一些小物件&#xff0c;大物件物品可以入手大型超声波清洗机&#xff0c;总之现在超声波清洗机已经衍生到可以在家使用&#xff0c;不再是在眼镜店看到它的身影或者是一些工业领域上&#xff0c;…

FL Studio2024重磅更新 带你了解FL21.2最新版本功能

FL Studio2024是功能强大的音乐制作解决方案&#xff0c;使用旨在为用户提供一个友好完整的音乐创建环境&#xff0c;让您能够轻松创建、管理、编辑、混合具有专业品质的音乐&#xff0c;一切的一切都集中在一个软件中&#xff0c;只要您想&#xff0c;只要您需要&#xff0c;它…

clip-path,css裁剪函数

https://www.cnblogs.com/dzyany/p/13985939.html clip-path - CSS&#xff1a;层叠样式表 | MDN 我们看下这个例子 polygon里有四个值分别代表这四个点相对于原图左上方的偏移量。 裁剪个五角星

六、ZooKeeper Java API操作

目录 1、引入maven坐标 2、节点的操作 这里操作Zookeeper的JavaAPI使用的是一套zookeeper客户端框架 Curator ,解决了很多Zookeeper客户端非常底层的细节开发工作 。 Curator包含了几个包:

ansible模块

目录 一、ansible的command模块 1.ad-hoc 2.playbook 3.command模块 二、ansible的shell模块 1.shell模块帮助 2.shell模块支持的参数和解释 3.简单试验 4.批量远程执行脚本 三、script模块 1.script模块帮助 2.shell模块支持的参数和解释 3.实践 四、ansible文件…

【学习记录】从0开始的Linux学习之旅——应用开发(helloworld)

一、概述 Linux操作系统通常是基于Linux内核&#xff0c;并结合GNU项目中的工具和应用程序而成。Linux操作系统支持多用户、多任务和多线程&#xff0c;具有强大的网络功能和良好的兼容性。本文主要讲述如何在linux系统上进行应用开发。 二、概念及原理 应用程序通过系统调用与…

Jmeter工具+ant+jenkins实现持续集成

jmeterantjenkins持续集成 一、下载并配置jmeter 首先下载jmeter工具&#xff0c;并配置好环境变量&#xff1b;参考&#xff1a; jmeter默认保存的是.jtl格式的文件&#xff0c;要设置一下bin/jmeter.properties,文件内容&#xff0c;保存jmeter.save.saveservice.output_f…