【数据结构】建堆算法复杂度分析及TOP-K问题

news2024/11/13 23:17:34

【数据结构】建堆算法复杂度分析及TOP-K问题

🔥个人主页大白的编程日记

🔥专栏数据结构


文章目录

  • 【数据结构】建堆算法复杂度分析及TOP-K问题
    • 前言
    • 一.复杂度分析
      • 1.1向下建堆复杂度
      • 1.2向上建堆复杂度
      • 1.3堆排序复杂度
    • 二.TOP-K问题
      • 2.1思路分析
      • 2.2代码实现
    • 后言

前言

哈喽,各位小伙伴大家好!上期我们讲了堆排序和建堆算法。今天我们就来分析一下他们的时间复杂度。话不多说,咱们进入正题。向大厂冲锋!

一.复杂度分析

我们都知道堆是一个完全二叉树。那他的高度h和节点数量N有什么关系呢?

那我们再来对比一下满二叉树和完全二叉树的高度h.

我们用大O渐进表示法看的话他们两个的高度h都可以认为是logN的量级
所以我们的堆的上下调整可以认为是logN,也就是高度次。

因为堆是完全二叉树,而满二叉树也是完全二叉树,所以为了方便证明
我们使用满二叉树来证明(时间复杂度本来看的就是近似值,多几个结点不影响最终结果):

1.1向下建堆复杂度

我们先分别算出第一层到h-1层的节点个数和该层节点的调整次数
然后再推出总的调整次数。

  • 推导

1.2向上建堆复杂度

我们先分别算出第2层到h层的节点个数和该层节点的调整次数
然后再推出总的调整次数。

  • 推导

所以向下建堆的时间复杂度是O(N),向上建堆的复杂度是O(N*logN).
所以以后我们都尽量使用向下调整建堆。因为他的效率更高。

1.3堆排序复杂度

现在我们来看一下我们堆排序的时间复杂度是多少呢?

  • 推导

    堆排序的复杂度是O(N*logN).

二.TOP-K问题

2.1思路分析

我们的堆除了可以用来排序还可以用来解决经典的TOP-K问题。
TOP-K问题:即求数据结合中前K个最大的元素或者最小的元素,一般情况下数据量都比较大。
比如:专业前10名、世界500强、富豪榜、游戏中前100的活跃玩家等。

  • 方法一
    我们很容易想到直接排序然后取出前K个即可。
    但是这个方法有个致命缺陷。
    如果数据量非常大,排序就不太可取了(可能数据都不能一下子全部加载到内存中)。

    我们发现这个方法在数据量太大的时候并不适用。
    那有什么其他好的方法吗?
  • 方法二
    最佳的方式就是用堆来解决,基本思路如下:
    1 .用数据集合中前K个元素来建堆
    前k个最大的元素,则建K个数的小堆
    前k个最小的元素,则建K个数的大堆
    2 . 用剩余的N-K个元素依次与堆顶元素来比较,
    如果比堆顶元素还要大或小(小堆大 大堆小)则替换堆顶元素,然后向下调整重新建堆。

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

为什么呢?

  • 证明

    我们通过N-K次比较就可以筛选出N-K个不满足最大前K个数的数
    剩下在堆的数就是最大的前K个。
  • 疑问

我们用反证法可以得知这种情况不存在。

2.2代码实现

  • 生成数据函数
    我们先用srand生成不同的种子防止生成的随机数是伪随机数。
    然后fopen打开文件。循环生成随机数然后写入文件即可。最后关闭文件。
void CreatData()
{
	int n = 100000;//生成10万个数据
	srand(time(0));//生成不同的种子
	FILE* pf = fopen("test.txt", "w");//打开文件
	for (int i = 0; i < n; i++)
	{
		int x = rand() % 100001+i;//生成随机数
		fprintf(pf, "%d\n", x);//写数据
	}
	fclose(pf);//关闭文件
	pf = NULL;
}


这样10万个数据就生成好了。

  • 比较函数

我们先接收k。然后开好k个数是堆空间。
然后从文件读取前k个数并填充到堆里面。然后建堆
然后继续读取文件里的数据直到文件末尾(返回EOF)
然后当数据大于堆顶元素是在进堆,然后重新调整建堆即可。

void test()
{
	int k;
	printf("请输入前K个数:");
    scanf("%d", &k);
	int* a = (int*)malloc(sizeof(int) * k);//开空间建堆
	FILE* pf = fopen("test.txt", "r");
	for (int i = 0; i < k; i++)
	{
		fscanf(pf, "%d", &a[i]);
	}//填充数据
	for (int i = (k - 1 - 1) / 2; i >= 0; i--)
	{
		AdjustDown(a, k, i);
	}//建小堆
	int x;
	while (fscanf(pf, "%d", &x) !=EOF)
	{
		if (x > a[0])
		{
			a[0] = x;
			AdjustDown(a, k, 0);
		}
	}//对比
	for (int i = 0; i < k; i++)
	{
		printf("%d ", a[i]);
	}//打印
}
  • 检验

那我们如何确保这10个数一定是最大的呢?万一我们的算法写错不是最大的前10个数怎么办?










那我们就可以在不同的地方在一些k标点。
也就是K个很大的数,确保他们是最大的前K个。
然后只需要看结果是不是这k个数即可。

大家发现结果就是我们手动给的这10个数。说明我们的程序时没问题的。

后言

这就是建堆算法复杂度分析及TOP-K问题。这里涉及到许多数学知识。大家可以多看几遍证明图。今天就分享到这里。感谢大佬们垂阅!咱们下期见!拜拜~

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

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

相关文章

C++高性能通信:了解Iceoryx与零拷贝技术的实现与应用

文章目录 0. 引言1. Iceoryx使用到的零拷贝技术1.1 零拷贝技术概述1.2 零拷贝的优势1.3 Iceoryx零拷贝的实现1.4 信息轮询与信号触发 2. Iceoryx的核心概念2.1 RouDi (iox-roudi)2.2 Runtime2.3 Publisher2.4 Subscriber2.5 Topic 3. Iceoryx使用示例3.1 发布者程序3.2 订阅者程…

1万+台网络设备运维如何选择支撑工具?

针对1万台网络设备的运维管理&#xff0c;需要采取一套系统化、自动化且高效的管理方法与策略。“工欲善其事&#xff0c;必先利其器”&#xff0c;以下结合一些关键步骤探讨运维支撑软件工具的方案。 1 建立完善的设备档案 设备信息记录&#xff1a; 为每台设备建立详细的…

科研成果 | 高精尖中心取得高性能区块链交易调度技术突破

近日&#xff0c;未来区块链与隐私计算高精尖创新中心研究团队在区块链交易效率方面取得突破性进展&#xff0c;最新成果“高性能区块链交易调度引擎”首次为长安链带来高并行度的交易调度&#xff0c;充分利用现有计算资源&#xff0c;显著提升长安链交易处理速度。 随着区块…

安卓单机游戏:《植物大战僵尸:重生》一款深受玩家喜爱的塔防游戏

一款深受玩家喜爱的塔防游戏&#xff0c;在这个游戏中&#xff0c;玩家需要通过种植不同类型的植物来阻止不断涌来的僵尸入侵&#xff0c;而每种植物都有自己的能力与特点&#xff0c;游戏画面和音效都非常出色&#xff0c;剧情也十分有趣&#xff0c;难度不断升级&#xff0c;…

JAVA代码审计JAVA0基础学习(需要WEB基础知识)DAY2

JAVA 在 SQL执行当中 分为3种写法&#xff1a; JDBC注入分析 Mybatis注入分析 Hibernate注入分析 JDBC 模式不安全JAVA代码示例部分特征 定义了一个 sql 参数 直接让用户填入id的内容 一个最简单的SQL语句就被执行了 使用安全语句却并没有被执行 Mybatis&#xff1a; #…

第13周 简历职位功能开发与Zookeeper实战

第13周 简历职位功能开发与Zookeeper实战 本章概述1. Mysql8窗口函数over使用1.1 演示表结构与数据1.2 案例1:获取男女总分数1.3 案例2****************************************************************************************本章概述 1. Mysql8窗口函数over使用 参考案例…

行业不同怎么选企业管理咨询公司

在选择企业管理咨询公司时&#xff0c;不同行业的企业往往面临着各自独特的挑战和需求。因此&#xff0c;选择一家适合自身行业特点、能够提供专业且有针对性的咨询服务的管理咨询公司至关重要。本文将从行业差异的角度出发&#xff0c;探讨如何根据企业所在行业的不同&#xf…

二维码的生成与识别(python)

二维码生成 from PIL import Image import qrcode from qrcode.image.styledpil import StyledPilImage from qrcode.image.styles.colormasks import SolidFillColorMask from qrcode.image.styles.moduledrawers import SquareModuleDrawer# 创建二维码对象 qr qrcode.QRCo…

智能编程,一触即发:使用AIGC优化CSS——提升前端开发效率与质量

文章目录 一、AIGC在CSS优化中的应用场景智能代码生成自动布局调整性能优化建议样式和色彩建议 二、使用AIGC优化CSS的具体步骤明确需求选择AIGC工具输入描述或设计稿审查和调整集成和测试 三、AIGC优化CSS的优势与挑战优势&#xff1a;挑战&#xff1a; 《CSS创意项目实践&…

vue3前端开发-小兔鲜项目-登录和非登录状态下的模板适配

vue3前端开发-小兔鲜项目-登录和非登录状态下的模板适配&#xff01;有了上次的内容铺垫&#xff0c;我们可以根据用户的token来判定&#xff0c;到底是显示什么内容了。 1&#xff1a;我们在对应的导航组件内修改完善一下内容即可。 <script setup> import { useUserSt…

ATE测试设备ATECLOUD专注于电源模块、电源芯片和射频组件测试

在追求效率与精度的时代背景下&#xff0c;电子测试测量行业迎来了ATE自动化测试设备的革新。这一设备的出现&#xff0c;不仅简化了测试流程&#xff0c;还大幅提高了测试的准确性和速度。 新ATE自动化测试设备&#xff1a;ATECLOUD测试平台 纳米软件深耕电测行业16年&#xf…

算法 day4 【双指针、快慢指针、环形链表】链表下

⚡刷题计划day4继续&#xff0c;可以点个免费的赞哦~ 下一期将会开启哈希表刷题专题&#xff0c;往期可看专栏&#xff0c;关注不迷路&#xff0c; 您的支持是我的最大动力&#x1f339;~ 目录 ⚡刷题计划day4继续&#xff0c;可以点个免费的赞哦~ 下一期将会开启哈希表刷题…

无法连接网络打印机0x00000709原因分析及多种解决方法

在日常办公和生活中&#xff0c;打印机是不可或缺的重要设备。然而&#xff0c;有时在连接打印机的过程中&#xff0c;我们可能会遇到错误代码0x00000709的提示。有更新补丁导致的、有访问共享打印机服务异常、有访问共享打印机驱动异常等问题导致的&#xff0c;针对访问共享打…

实验三 FPGA使用Verilog HDL设计加法器

实验目的 掌握使用Vivado软件进行设计、综合、仿真、布线的方法。掌握FPGA程序的下载方法。掌握使用Verilog HDL设计加法器的方法。 实验要求 采用Verilog HDL语言设计加法器&#xff0c;实现两个4位数的相加运算&#xff0c;并将结果通过LED灯或数码管显示出来。对设计进行综…

如何通过集成软件授权管理系统推动企业业务增长?

软件货币化已经成为许多企业商业成功的关键&#xff0c;随着全球数字化进程不断深入&#xff0c;其重要性也在不断增加。将许可解决方案优化集成到现有系统中&#xff0c;已成为从接收到订单到交付和激活许可的任何高效流程的基本要素。 软件货币化无处不在 无论是传统的软件企…

[言简意赅] Matlab生成FPGA端rom初始化文件.coe

&#x1f38e;Matlab生成FPGA端rom初始化文件.coe 本文主打言简意赅。 函数源码 function gencoeInitialROM(width, depth, signal, filepath)% gencoeInitialROM - 生成 Xilinx ROM 初始化格式的 COE 文件%% 输入参数:% width - ROM 数据位宽% depth - ROM 数据深度% s…

在 LCD 上显示 png 图片-I.MX6U嵌入式Linux C应用编程学习笔记基于正点原子阿尔法开发板

在 LCD 上显示 png 图片 PNG 简介 无损压缩&#xff1a;PNG 使用 LZ77 派生算法进行无损压缩&#xff0c;确保图像质量不受损&#xff0c;且压缩比高 体积小&#xff1a;通过高压缩比&#xff0c;PNG 文件体积小&#xff0c;适合网络传输 索引彩色模式&#xff1a;PNG-8 格式…

Unity UGUI 之 RectTransform

本文仅作学习笔记与交流&#xff0c;不作任何商业用途 本文包括但不限于unity官方手册&#xff0c;唐老狮&#xff0c;麦扣教程知识&#xff0c;引用会标记&#xff0c;如有不足还请斧正 Unity - Manual: Rect Transform 1.Rect Transform是什么 2.轴心与锚点的映射关系 首先…

获取后端返回的图形验证码

如果后端返回的直接就是一个图形&#xff0c;有以下几种方式展示 一、直接在img标签里面的src里面调用接口 <img :src"dialogSrc" class"photo" alt"验证码图片" click"changeDialog">let orgUrl "/api/captcha" …

论文解读:DiAD之SG网络

目录 一、SG网络功能介绍二、SG网络代码实现 一、SG网络功能介绍 DiAD论文最主要的创新点就是使用SG网络解决多类别异常检测中的语义信息丢失问题&#xff0c;那么它是怎么实现的保留原始图像语义信息的同时重建异常区域&#xff1f; 与稳定扩散去噪网络的连接&#xff1a; S…