调建堆的时间复杂度的计算与topK问题

建堆复杂度的计算

向下调整建堆

第一层有2^0个节点,最坏向下调整h-1次,第二层有2^1个节点,最坏向下调整h-2次,以此类推,将每一层所有节点最坏情况需要调整的次数相加,就能得到一个式子:

T(h) = 2^0 *(h-1) + 2^1 * (h-2) + 2^2 * (h-3) + ... + 2^{h-3} * 2 +2^{h-2}*1

最后到达(n-1)层,有2^{h-2}个节点,最坏需要向下调整1次.

而要求出该和式的计算,利用错位相减法,两边同乘2,再两式相减即可得

T(h) = 2^h - 1 - h

而我们又知道对于高度为h的满二叉树的节点个数与高度的关系

N=F(h) = 2^h -1

带入原式可得

对于N来说,对数的数量级可以忽略不计.

所以向下调整建堆时间复杂度是O(N).

向上调整建堆

同样写出堆的总调整数公式

2^1*1 +2^2*2 +2^3*3+... + 2^{h-2}*(h-2)+ 2^{n-1}*(h-1)

同样错位相减并带入节点数与树高度之间关系可得

对于nlogn来说,n的数量级可以忽略不计.

向上调整建堆时间复杂度是O(NlogN).

故在堆排序中只用向下调整建堆即可.

topk问题

在所有数据中找到最大(小)的k个数.

1.堆排序

将所有数据存储到堆里面,再进行堆排序即可,但如果要求低内存我们就可以分k次,每次找10个,再将k个查找的堆中找到的共10k个数据再进行堆排序即可。代码如下:

void TestHeap1()
{int a[] = { 4,2,8,1,5,6,9,7,3,2,23,55,232,66,222,33,7,1,66,3333,999, 15155 };HP hp;HPInit(&hp);for (size_t i = 0; i < sizeof(a) / sizeof(int); i++){HPPush(&hp, a[i]);}printf("\n");*///找出最大的前k个int k = 0;scanf("%d", &k);while (k--){printf("%d ", HPTop(&hp));HPPop(&hp);}printf("\n");HPDestroy(&hp);
}

2.建k个数的小堆

剩下的数与栈顶数据相比较,如果比栈顶数据大,就覆盖并且向下调整,这样,这个k个数的小堆就是我们所要的最大的那k个数.

先创建数据

void CreateNDate()
{// 造数据int n = 100000;srand(time(0));const char* file = "data.txt";FILE* fin = fopen(file, "w");if (fin == NULL){perror("fopen error");return;}for (int i = 0; i < n; ++i){int x = (rand() + i) % 10000000;//保证其小于一千万fprintf(fin, "%d\n", x);//将数据导入data.txt中}fclose(fin);
}

创建一个数组

int* kminheap = (int*)malloc(sizeof(int) * k);
if (kminheap == NULL)
{perror("malloc fail!");return;
}

再打开数据文件并读取其中的前k个数

const char* file = "data.txt";
FILE* fout = fopen(file, "r");
if (fout == NULL)
{perror("fopen error");return;
}// 读取文件中前k个数
for (int i = 0; i < k; i++)
{fscanf(fout, "%d", &kminheap[i]);
}

再建立k个数的小堆,并读取剩下的N-k个数.

// 建K个数的小堆
for (int i = (k - 1 - 1) / 2; i >= 0; i--)//最后一个节点的下标减一再除以二得到最后一个非叶子节点
{AdjustDown(kminheap, k, i);
}// 读取剩下的N-K个数
int x = 0;
while (fscanf(fout, "%d", &x) > 0)//fscanf失败返回-1,所以这里我们让其大于0即可
{if (x > kminheap[0]){kminheap[0] = x;//将此数据与堆顶数据交换AdjustDown(kminheap, k, 0);}
}printf("最大前%d个数:", k);
for (int i = 0; i < k; i++)
{printf("%d ", kminheap[i]);//此时堆里数据就是最大的前k个
}
printf("\n");

整合起来

void TestHeap3()
{int k;printf("请输入k>:");scanf("%d", &k);int* kminheap = (int*)malloc(sizeof(int) * k);if (kminheap == NULL){perror("malloc fail");return;}const char* file = "data.txt";FILE* fout = fopen(file, "r");if (fout == NULL){perror("fopen error");return;}// 读取文件中前k个数for (int i = 0; i < k; i++){fscanf(fout, "%d", &kminheap[i]);}// 建K个数的小堆for (int i = (k - 1 - 1) / 2; i >= 0; i--)//最后一个节点的下标减一再除以二得到最后一个非叶子节点{AdjustDown(kminheap, k, i);}// 读取剩下的N-K个数int x = 0;while (fscanf(fout, "%d", &x) > 0){if (x > kminheap[0]){kminheap[0] = x;AdjustDown(kminheap, k, 0);}}printf("最大前%d个数:", k);for (int i = k - 1; i >= 0; i--)//最后将数组数据倒序打印出来就可以达成数据由大到小的打印了
{printf("%d ", kminheap[i]);
}printf("\n");
}

这里我们创建了10万个数据,并且我主动将其中的几个数据加上几个0检测算法是正确的.

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

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

相关文章

FanySkill源文件修改,快捷键以及新增任务栏选项

FanySkill源文件修改&#xff0c;快捷键以及新增任务栏选项 一、文件下载二、快捷键设置三、任务栏四、本人配置 一、文件下载 自行去PCB联盟网下载&#xff0c;因为那边下载要联盟币&#xff0c;我不清楚我免费提供会不会给我带来没必要的损失&#xff0c;敬请谅解。 要下载的…

怎么为自己的VPS选择合适的CPU和RAM?

为网站选择VPS&#xff08;虚拟专用服务器&#xff09;与为家庭或办公室选择台式机或笔记本电脑没有什么不同。基本上&#xff0c;您要做的就是查看硬件配置并比较功能和价格。 然而&#xff0c;虽然您可能对个人计算机所需的资源类型有一个粗略的估计&#xff0c;但为服务器获…

一文理清OCR的前世今生

AI应用开发相关目录 本专栏包括AI应用开发相关内容分享&#xff0c;包括不限于AI算法部署实施细节、AI应用后端分析服务相关概念及开发技巧、AI应用后端应用服务相关概念及开发技巧、AI应用前端实现路径及开发技巧 适用于具备一定算法及Python使用基础的人群 AI应用开发流程概…

队列(数据结构篇)

数据结构之队列 队列(queue) 概念&#xff1a; 队列也是一种线性表&#xff0c;使用队列时插入在一端进行而删除则在另一端进行&#xff0c;队列的基本操作是入队&#xff0c;它是在表的末端(也叫做队尾)插入一个元素&#xff0c;出队&#xff0c;它是删除在**表的开头(**队…

Springboot 项目启动时扫描所有枚举并存入缓存(redis)

为什么这么做? 为了springboot 注解属性转换字典方便一点(使用缓存的方式在Springboot 启动时获取字典数据) 在启动时会扫描com.vehicle.manager.core.enumerate包下的所有枚举(包括类中的内部枚举),并取出对应属性以json的方式存入redis 目录结构如下: RedisUtil可以在Red…

DLT645电表数据 转IEC104项目案例

案例说明 设置网关采集DLT645电表数据数据把采集的数据转成IEC104协议转发给其他系统。 VFBOX网关工作原理 VFBOX网关是协议转换网关&#xff0c;是把一种协议转换成另外一种协议。网关可以采集西门子&#xff0c;欧姆龙&#xff0c;三菱&#xff0c;AB PLC&#xff0c;DLT64…

南开大学漏洞报送证书【文尾有福利】

证书介绍 获取来源&#xff1a;edusrc&#xff08;教育漏洞报告平台&#xff09; url&#xff1a;教育漏洞报告平台(EDUSRC) 兑换价格&#xff1a;30金币​ 获取条件&#xff1a;南开大学任意中危或以上级别漏洞 证书规格&#xff1a;证书做了木框装裱&#xff0c;显得很高…

我工作中用Redis的10种场景

Redis作为一种优秀的基于key/value的缓存&#xff0c;有非常不错的性能和稳定性&#xff0c;无论是在工作中&#xff0c;还是面试中&#xff0c;都经常会出现。 今天这篇文章就跟大家一起聊聊&#xff0c;我在实际工作中使用Redis的10种场景&#xff0c;希望对你会有所帮助。 …

竞赛选题 python opencv 深度学习 指纹识别算法实现

1 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; python opencv 深度学习 指纹识别算法实现 &#x1f947;学长这里给一个题目综合评分(每项满分5分) 难度系数&#xff1a;3分工作量&#xff1a;4分创新点&#xff1a;4分 该项目较为新颖…

springBoot高校宿舍交电费系统-计算机毕业设计源码031552

摘 要 科技进步的飞速发展引起人们日常生活的巨大变化&#xff0c;电子信息技术的飞速发展使得电子信息技术的各个领域的应用水平得到普及和应用。信息时代的到来已成为不可阻挡的时尚潮流&#xff0c;人类发展的历史正进入一个新时代。在现实运用中&#xff0c;应用软件的工作…

忘记 iPhone 密码:如果忘记密码,如何解锁 iPhone

为了提高个人数据的安全性&#xff0c;用户通常会为不同的帐户和设备创建不同的复杂密码。虽然较新的 iPhone 型号具有生物识别和面部解锁功能&#xff0c;但这些功能并不总是有效 - 如果您忘记了 iPhone 的密码&#xff0c;您可能会遇到麻烦。 iPhone 用户和 Android 用户一样…

MYSQL 四、mysql进阶 4(索引的数据结构)

一、为什么使用索引 以及 索引的优缺点 1.为什么使用索引 索引是存储引擎用于快速找到数据记录的一种数据结构&#xff0c;就好比一本教科书的目录部分&#xff0c;通过目录中找到对应文章的页码&#xff0c;便可快速定位到需要的文章。Mysql中也是一样的道理&#xff0c;进行数…

办公人必备宝藏网站,提升工作效率!

对于每个办公人来说&#xff0c;如何在繁杂的工作中保持高效&#xff0c;是每位职场人士追求的目标。其中&#xff0c;高效的工具和资源可以极大地提升我们的工作效率。下面小编就来和大家分享一些办公人必备的宝藏网站&#xff0c;提升大家的工作效率。 1. 办公人导航 办公人…

反激开关电源变压器设计2

实际计算 已知 Vin&#xff1a;AC176-264V Vo&#xff1a;5V Io2A Vmax264V*根号2373V PoVo*Io10W η0.8 PinPo/η12.5W DCM变压器&#xff0c;在开关电源的整个输入电压范围内满载工作时都工作在断续模式 CCM变压器&#xff0c;在开关电源的整个输入电压范围内满载工作时都工…

小程序开发的技术难点

小程序开发是一项技术难度较高的工作&#xff0c;需要开发者具备多方面的知识和技能&#xff0c;小程序开发的技术难点主要体现在以下几个方面。北京木奇移动技术有限公司&#xff0c;专业的软件外包开发公司&#xff0c;欢迎交流合作。 1. 多端兼容 小程序需要在微信、支付宝…

渗透测试基础(五) 获取WiFi密码

1. 前提条件 需要无线网卡&#xff0c;kali无法识别电脑自带的网卡。 2. 实验步骤&#xff1a; 2.1 查看网卡 命令&#xff1a;airmon-ng 2.2 启动网卡监听模式 命令airmon-ng start wlan0 检查下是否处于监听模型&#xff1a;ifconfig查看一下&#xff0c;如果网卡名加…

ARM64汇编0C - inlinehook

本文是ARM64汇编系列的完结篇&#xff0c;主要利用前面学过的知识做一个小实验 完整系列博客地址&#xff1a;https://www.lyldalek.top/article/arm 这里只讨论 ARM64 下的 inlinehook&#xff0c;做一个简单的demo&#xff0c;只是抛砖引玉&#xff0c;有兴趣了解更多细节的可…

WordPress主题 酱茄免费主题

酱茄free主题由酱茄开发的一款免费开源的WordPress主题&#xff0c;主题专为WordPress博客、资讯、自媒体网站而设计&#xff0c;遵循GPL V2.0开源协议发布。 运行环境 酱茄Free主题当前版本&#xff1a;2020.11.25 V1.0.0 支持WordPress版本&#xff1a;5.4 兼容Chrome、Fire…

word复制技巧二则

1 纵向复制 按下Alt键&#xff0c;按下鼠标左键拖动&#xff0c;选中要纵向复制的内容&#xff0c;如下图&#xff0c; 再粘贴即可&#xff1b; 2 整页复制 在页的任意位置单击&#xff0c;然后按CtrlA&#xff0c;这会选中整页&#xff1b;然后再复制粘贴即可&#xff1b;

更换域名流程记录

华为云的服务器&#xff0c;阿里云购买的域名。 1.购买域名 2.在域名服务商绑定服务器ip&#xff08;以阿里云为例&#xff09; 控制台->域名控制台->域名列表->点击域名->域名解析->添加记录 记录类型填A , 主机记录“”或“www”&#xff0c;记录值填服务器i…