向上调整建堆与向下调整建堆的时间复杂度 AND TopK问题

目录

  • 前言
  • 建堆的时间复杂度
  • TOPK问题
  • 总结

前言

本篇旨在介绍使用向上调整建堆与向下调整建堆的时间复杂度. 以及topk问题

博客主页: 酷酷学!!!
感谢关注~

建堆的时间复杂度

堆排序是一种优于冒泡排序的算法, 那么在进行堆排序之前, 我们需要先创建堆, 为什么说堆排序的是优于冒泡排序的呢? 那么这个建堆的时间复杂度是多少呢?

void HeapSort(int* a, int n)
{//降序//创建小堆//向下调整创建,从最有一个非叶子节点//时间复杂度O(N)for (int i = (n-1-1)/2; i>=0; i--){Adjustdown(a, n, i);}//堆创建之后,交换第一个节点与最后一个节点,//时间复杂度为O(N*logN)int end = n-1;while (end > 0){Swap(&a[0], &a[end]);Adjustdown(a, end, 0);end--;}
}

首先来看向下调整算法建堆的时间复杂度, 因为堆是完全二叉树,而满二叉树也是完全二叉树,此处为了简化使用满二叉树来证明(时间复杂度本来看的就是近似值,多几个结点不影响最终结果):

假设高度为h的二叉树, 结点的个数为N, 可以计算出高度h与结点个数之间的关系如下图所示:

在这里插入图片描述

向下调整算法, 从最后一个非叶子结点开始向下调整, 也就是第h-1层, 需要向下移动一层, 第h-2层需要向下移动2层, … , 第一层则需要向下移动h-1层, 第二层的结点需要向下移动h-2层. 依次类推, 如图所示.
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
可以看出节点数量多的层调整次数少, 结点数量少的层调整次数多 . 错位相减法则可以计算出T(N) = 2^h - 1 - h, 带入h与N的关系则得出向下调整建堆的时间复杂度为O(N).

void Heapsort(int* a,int n)
{//时间复杂度为O(N*logN)for (int i = 1; i < n; i++){AdjustUP(a, i);}//时间复杂度为O(N*logN)int end = n - 1;while (end > 0){Swap(&a[0], &a[end]);AdjustDown(a, end, 0);end--;}
}

使用向上调整建堆, 计算其时间复杂度, 如下

在这里插入图片描述
总计调整次数为
在这里插入图片描述
使用错位相减法计算:

在这里插入图片描述
可以看出结点数多的层, 调整次数也多, 结点数少的层, 调整次数少, 时间复杂度为O(N*logN), 所以一般建堆都采用向下调整建堆法.

TOPK问题

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

  1. 用数据集合中前K个元素来建堆

前k个最大的元素,则建小堆
前k个最小的元素,则建大堆

  1. 用剩余的N-K个元素依次与堆顶元素来比较,不满足则替换堆顶元素

将剩余N-K个元素依次与堆顶元素比完之后,堆中剩余的K个元素就是所求的前K个最小或者最大的元素。

例如: 求十万个数据中最大的前K个数, 要求只有1kb内存, 这些数据存储在磁盘中

首先先用前k个数建一个小堆, 剩下的N-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);}fclose(fin);
}

读取数据, 并且用前k个数据创建一个小堆, 然后读取剩下的数据, 如果比堆顶数据大, 就替代堆顶数据进入堆, 然后向下调整堆.

void TestHeap()
{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 = 0; i < k; i++){printf("%d ", kminheap[i]);}printf("\n");
}
int main()
{CreateNDate();TestHeap();return 0;
}

总结

建堆的时间复杂度为O(N), 使用堆排序的时间复杂度为O(N*logN), 而使用冒泡排序的时间复杂度为O(N^2), 故堆排序的效率明显高于冒泡排序, 而topk则解决了使用较小内存而求取一堆数据中最大或者最小的前k个数据.

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

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

相关文章

Backend - postgresSQL DB 存储过程(数据库存储过程)

目录 一、存储过程的特性 &#xff08;一&#xff09;作用 &#xff08;二&#xff09;特点 &#xff08;三&#xff09;编码结构的区别 二、定时执行存储过程 三、2种编码结构 &#xff08;一&#xff09;函数结构 1. SQL代码 2. 举例 &#xff08;1&#xff09;例1-循…

考场作弊行为自动抓拍分析系统

考场作弊行为自动抓拍分析系统采用了AI神经网络和深度学习算法&#xff0c;考场作弊行为自动抓拍分析系统通过人形检测和骨架勾勒等技术&#xff0c;实时计算判断考生的异常动作行为。通过肢体动作识别技术&#xff0c;系统可以详细分析考生的头部和手部肢体动作&#xff0c;进…

如何提高学习思考能力

目录 前言第一章、学习能力1.1)学习能力介绍1.1.1 感知能力与提升1.1.2 想象能力与提升1.1.3 理解能力与提升1.1.4 逻辑能力与提升1.1.5 记忆能力与提升1.1.6 专注能力与提升1.1.7 自控能力与提升1.2)学习能力提升总结1.3.1 走出舒适区1.3.2 积极的环境1.3.3 情绪影响1.3.4 身…

乡村振兴的乡村旅游新模式:挖掘乡村旅游资源,创新旅游开发方式,打造乡村旅游新品牌,助力美丽乡村建设

目录 一、引言 二、乡村旅游资源挖掘 1、自然景观资源 2、人文历史资源 3、农业产业资源 三、旅游开发方式创新 1、多元化旅游产品 2、体验式旅游模式 3、智慧旅游建设 四、乡村旅游新品牌打造 1、品牌定位与策划 2、品牌传播与推广 3、品牌维护与提升 五、助力美…

当代家庭教育杂志社《当代家庭教育》杂志社24年第6期目录

家庭教育资讯 《家庭教育蓝皮书2024:中国家庭养育环境报告》出炉 4 2024年4月至7月北京市将开展“双减”专项行动 5 小学生玩“烟卡”到底该不该禁&#xff1f; 5 家庭教育理论探索 新时代家长家庭教育素养&#xff1a;意涵、关键要素及其培育 周起煌; 6-10 …

【游戏】数30必胜玩法

游戏规则 规则&#xff1a;参与人数 2 2 2人&#xff0c;轮流交替数依次递增 1 1 1数数&#xff0c;最少数 1 1 1个数&#xff0c;最多数 n n n个数&#xff0c;数到 30 30 30的人为输家&#xff01; x { N 1 P 1 m ( 30 − 1 ) ( m o d ( n 1 ) ) if m 1 N m P 2 m P…

头歌03- 01背包

""" 题目&#xff1a;有n个重量分别为w{w_1,w_2,…,w_n}的物品&#xff0c;他们的价值分别为v{v_1,v_2,…,v_n}&#xff0c;给定一个容量为V的背包。 设计从这些物品中选取一部分物品放入该背包的方案&#xff0c;每个物品要么选中要么不选中&#xff0c;要求选…

轻松上手ClickHouse:ClickHouse入门

引言 在数字化时代&#xff0c;大数据处理和分析已经成为了各行各业不可或缺的一环。而ClickHouse&#xff0c;作为一款高性能的列式数据库管理系统&#xff0c;以其卓越的查询性能和灵活的扩展性&#xff0c;赢得了众多企业和开发者的青睐。本文将带领大家走进ClickHouse的世…

CCF-GESP 等级考试 2023年12月认证C++一级真题

2023年12月真题 一、单选题&#xff08;每题2分&#xff0c;共30分&#xff09; 第 1 题 以下C不可以作为变量的名称的是( )。 A. CCF GESPB. ccfGESPC. CCFgespD. CCF_GESP 第 2 题 C表达式10 - 3 * (2 1) % 10的值是( )。 A. 0B. 1C. 2D. 3 第 3 题 假设现在是上午⼗点&…

Python基础学习笔记(四)——运算符

目录 算术运算符1. 四则运算2. 整除3. 取模4. 求幂 赋值运算符1. 链式赋值2. 参数赋值3. 系列解包赋值 关系运算符身份运算符成员运算符逻辑运算符位运算符1. 按位运算2. 移位运算 优先级 算术运算符 1. 四则运算 # 加减乘除:除法结果为浮点数 print(12, 1-2, 1*2, 2/1)3 -1 …

Kubernetes常用命令

目录 一.资源管理办法 1.陈述式资源管理方法 &#xff08;1&#xff09;kubernetes 集群管理集群资源的唯一入口是通过相应的方法调用 apiserver 的接口 &#xff08;2&#xff09;kubectl 是官方的CLI命令行工具&#xff0c;用于与 apiserver 进行通信&#xff0c;将用户在…

VC++学习(3)——认识MFC框架,新建项目,添加按钮

目录 引出第三讲 MFC框架新建项目Windows搜索【包含内容的搜索】如何加按钮添加成员变量添加成功 添加按钮2杂项 总结 引出 VC学习&#xff08;3&#xff09;——认识MFC框架&#xff0c;新建项目&#xff0c;添加按钮 MFC(Microsoft Foundation Classes)&#xff0c;是微软公…

零基础小白撸空投攻略:空投流程是什么样的? 如何操作?

在Web3的世界中&#xff0c;空投&#xff08;Airdrop&#xff09;是一种常见的营销和推广策略&#xff0c;通过向特定用户群体免费分发代币&#xff0c;项目方希望能够吸引更多的用户和关注。对于许多刚刚接触加密货币和区块链的新手来说&#xff0c;都会疑惑空投的流程究竟是什…

AI - GPT-4o是什么?

一、定义&#xff1a; GPT-4o是OpenAI推出的最新旗舰级人工智能模型&#xff0c;它是GPT系列的一个重要升级&#xff0c;其中的"o"代表"Omni"&#xff0c;中文意思是“全能”&#xff0c;凸显了其多功能特性。该模型被设计为能够实时对音频、视觉和文本进…

Java-JavaQAList

一、Java基础 解释下什么是面向对象&#xff1f;面向对象和面向过程的区别&#xff1f;面向对象的三大特性&#xff1f;分别解释下&#xff1f;JDK、JRE、JVM 三者之间的关系&#xff1f;重载和重写的区别&#xff1f;Java 中是否可以重写一个 private 或者 static 方法&#…

LeetCode-Pow(x, n)【递归 数学】

[TOC](LeetCode-Pow(x, n)【递归 数学】) 题目描述&#xff1a; 实现 pow(x, n) &#xff0c;即计算 x 的整数 n 次幂函数&#xff08;即&#xff0c;xn &#xff09;。 示例 1&#xff1a; 输入&#xff1a;x 2.00000, n 10 输出&#xff1a;1024.00000 示例 2&#xf…

HTML | 在IDEA中配置Tomcat时遇到的一些问题的解决办法

目录 IDEA中没有web文件夹目录 Tomcat在哪里配置服务器 IDEA中没有web文件夹目录 首先说在IDEA中没有web这个文件夹的解决办法 在菜单栏中帮助中点击查找操作搜索添加框架支持&#xff08;因为我的IDEA会出现无法点击这个操作&#xff0c;所以我对该操作添加了快捷键&#xf…

聊聊 JSON Web Token (JWT) 和 jwcrypto 的使用

哈喽大家好&#xff0c;我是咸鱼。 最近写的一个 Python 项目用到了 jwcrypto 这个库&#xff0c;这个库是专门用来处理 JWT 的&#xff0c;JWT 全称是 JSON Web Token &#xff0c;JSON 格式的 Token。 今天就来简单入门一下 JWT。 官方介绍&#xff1a;https://jwt.io/intr…

邮件系统中的CC和BCC含义

一、背景 我们在发邮件时&#xff0c;有时会看到或用到CC和BCC相关的功能&#xff0c;下面简要介绍一下。 二、CC CC&#xff1a;Carbon Copy&#xff0c;也就是抄送&#xff0c;是一种电子邮件发送方式。 三、BCC BCC&#xff1a;Blind Carbon Copy&#xff0c;也就是密件…

谓词逻辑(一)

一、句子的谓词符号化 谓词逻辑&#xff0c;也叫一阶逻辑&#xff0c;它对每个最简单的命题尽一步进行分解。 1个体词&#xff1a;可以独立存在的客体。 2谓词&#xff1a;描述一个个体词的属性或多个个体词之间的关系&#xff08;可用一元函数和多元函数来理解&#xff09;…