堆的相关时间复杂度计算(C语言)

目录

前言

建堆的时间复杂度

向上调整建堆的时间复杂度

向下调整建堆的时间复杂度

维护堆的时间复杂度

top K问题的时间复杂度


前言

        在前面的三篇文章中我们成功的实现了堆排序的升降序以及基于堆的top K问题,现在我们来解决它们的时间复杂度问题

建堆的时间复杂度

关于建堆的时间复杂度计算我们放在了:大小堆的实现(C语言)中讲解

向上调整建堆的时间复杂度

计算方式:此时所处层的结点个数 * 向上调整次数   

文字描述: 假设我们有一个具有 N 个节点的满二叉树,并且我们正在对其中某个节点进行向上调整。在最坏情况下,该节点可能需要一直交换到根节点位置才能满足堆性质。

公式描述:

向上调整建堆到叶子结点时就不再调整,假设向下调整建堆的累计调整次数是T(h),那么:

T(h) = 2^1 * 1 + 2^2 * 2 + ...... + 2^(h-2) * (h-2) + 2^(h-1) * (h-1)     ① 
2*T(h) = 2^2 * 1 + 2^3 * 2 + ...... + 2^(h-1) * (h-2) + 2^h * (h-1)      ②

②-①得:

T(h) = -(2^0 + 2^1 + 2^2 + ...... + 2^(h-2) + 2^(h-1)) + 2^h*(h-1)  +  2^0     ③

由等比数列求和公式得:

T(h) = -((2^h) - 1) + 2^h*(h-1) + 2^0     ④

又由于满二叉树高度h与总结点个数N之间的关系是h = log(N+1),故将④化简可得:

T(N) =  -N + (N+1)(log(N+1)-1) + 1

因此,向上调整建堆的时间复杂度为:O(N*logN)

向下调整建堆的时间复杂度

假设该堆为满二叉树,此时向下调整的情况是最坏的情况:

计算方式:此时所处层的结点个数 * 向下调整次数  

文字描述:假设有一个具有 N 个元素的完全二叉树(即堆),其中 h 是该二叉树的高度。在最坏情况下,需要将一个元素从根节点向下移动到底部层次,并且每一次都需要与其子节点进行比较和交换操作。 

公式描述:

向下调整建堆到叶子结点时就不再调整,假设向下调整建堆的累计调整次数是T(h),那么:

T(h) = 2^(h-2) * 1 + 2^(h-3) * 1 + ...... + 2^1 * (h-2) + 2^0 * (h-1)     ① 
2*T(h) = 2^(h-1) * 1 + 2^(h-2) * 1 + ...... + 2^2 * (h-2) + 2^1 * (h-1)     ②

②-①得:

T(h) = 2^(h-1) + 2^(h-2)  + ...... + 2^1 + 2^0 - h     ③

由等比数列求和公式得:

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

又由于满二叉树高度h与总结点个数N之间的关系是h = log(N+1),故将④化简可得:

T(N) =  N - log(N+1)

因此,向下调整建堆的时间复杂度为:O(N) 

结论:向下调整建堆的时间复杂度为O(N),向上调整建堆的时间复杂度为O(N*logN),因此更倾向于使用向下调整的方式建堆

向下调整向下调整建堆时间复杂度分别为O(logN)O(N)

维护堆的时间复杂度

//维护
int end = n - 1;
while (end > 0)
{Swap(&a[0], &a[end]);AdjustDown(a, end, 0);--end;
}

维护堆的时间复杂度为O(N*logN)

文字描述:

假设数组 a 的长度为 n,则循环会执行 n-1 次迭代,每次迭代都包括以下几个步骤:

  1. 交换首尾元素:通过调用 Swap 函数交换数组首尾元素,所需时间复杂度为 O(1)

  2. 向下调整:向下调整的时间复杂度为O(logN)

  3. 更新结束标志:将结束标志 end 减一,表示缩小待处理区间,所需时间复杂度为 O(1)

因此,时间复杂度O(n) = (N-1)logN = N*logN

公式描述:

在满二叉树中的总结点个数N为:
N = (2^0) + (2^1) + ... + 2^(h-1)

由等比数列求和公式得到:
N = (2^h - 1)

因此堆高度 h 与结点总数N的关系为:
h = log(N + 1)

最坏情况下,一个元素需要一直向下移动到叶子节点,此时它经过堆高度上所有层级:

所以时间复杂度为O(logN)

补充:时间复杂度计算的是输入规模与算法最坏执行时间之间的关系,在向下调整操作中,时间复杂度计算了堆的总结点个数 N 与一个结点最坏的调整次数所需的时间,这个时间又与结点的高度h有关而h=log(N+1),所以O(N) = log(N+1) = log(N)

top K问题的时间复杂度

文字描述:

利用堆解决top K问题可以分为两个阶段:

  1. 建立初始大小为 K 的最小堆:需要插入 K 个元素到空的初始堆中。每次插入操作都需要执行一次向上调整操作,时间复杂度为 O(logK)
    因此,在建立初始大小为 K 的最小堆时所需总比较和交换次数是 O(KlogK)

  2. 处理剩余 N-K 个元素:对于每个剩余元素,如果它大于当前最小值(即根节点),则替换并执行向下调整操作,以维护最新的 top k 元素,每次替换和向下调整都需要花费 O(logK) 的时间。
    因此,在处理剩余 N-K 个元素时所需总比较和交换次数是 O((N-K)logK)

因此,使用堆解决 Top K 问题的时间复杂度为 O(KlogK + (N-K)logK),其中 N 是输入元素的总数。如果 K 远小于 N,则该算法的时间复杂度可近似为 O(NlogK),因为 K 的值相对较小可忽略不计。

~over~

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

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

相关文章

我有才专属定制适合个人的知识付费平台,打造个性化品牌与自主管理体验

在当今数字化时代,知识付费平台已经成为人们获取专业知识、提升自身素质的重要渠道。然而,公共知识付费平台虽然内容丰富,但难以满足个人或企业个性化的需求和品牌打造。因此,我们提出了专属定制适合个人的知识付费平台的概念&…

108. 将有序数组转换为二叉搜索树

给你一个整数数组 nums ,其中元素已经按 升序 排列,请你将其转换为一棵 高度平衡 二叉搜索树。 高度平衡 二叉树是一棵满足「每个节点的左右两个子树的高度差的绝对值不超过 1 」的二叉树。 示例 1: 输入:nums [-10,-3,0,5,9] 输…

2023年最新prometheus + grafana搭建和使用

一、安装prometheus 1.1 安装 prometheus官网下载地址 sudo -i mkdir -p /opt/prometheus #移动解压后的文件名到/opt/,并改名prometheus mv prometheus-2.45 /opt/prometheus/ #创建一个专门的prometheus用户: -M 不创建家目录, -s 不让登录 useradd…

面向AOP(2)spring

我是南城余!阿里云开发者平台专家博士证书获得者! 欢迎关注我的博客!一同成长! 一名从事运维开发的worker,记录分享学习。 专注于AI,运维开发,windows Linux 系统领域的分享! 本…

ChatGPT是科学还是艺术?

OpenAI最近谈到GPT4变懒的问题,说“它更像是多人共同参与的艺术创作”,那到底大模型是科学还是艺术?

Spring Boot 3 集成 MyBatis详解

MyBatis是一款开源的持久层框架,它极大地简化了与数据库的交互流程。与类似Hibernate的ORM框架不同,MyBatis更具灵活性,允许开发者直接使用SQL语句与数据库进行交互。Spring Boot和MyBatis分别是两个功能强大的框架,它们的协同使用…

HarmonyOS4.0从零开始的开发教程10Video组件的使用

HarmonyOS(九)Video组件的使用 概述 在手机、平板或是智慧屏这些终端设备上,媒体功能可以算作是我们最常用的场景之一。无论是实现音频的播放、录制、采集,还是视频的播放、切换、循环,亦或是相机的预览、拍照等功能…

向日葵远程控制鼠标异常的问题

​ 在通过向日葵进行远程控制的时候,可能会遇到鼠标位置异常的问题。此时,不管怎么移动鼠标,都会停留在屏幕最上方,而无法点击到正确的位置。如图: 此时,如果启用了“被控端鼠标”功能,可以正…

dToF直方图之美_deadtime死区时间

上节在激光雷达多目标测距中有个问题为什么激光雷达不用做pile up算法,有人会有疑问,我看过很多人的简历,都把pile up量产校正算法写为最为自豪重要的算法攻坚,可能会吸引一波人的眼球。这要是在两三年前是值得被肯定的,但是如今随着dToF非常多量产项目落地,pile up研究不…

【Bootloader学习理解----跳转优化异常】

笔者接着来介绍一下Bootloader的跳转代码以及优化 1、跳转代码理解 跳转代码可能要涉及到芯片架构的知识,要跳转到对应的位置,还要设置相关的SP 堆栈指针,具体可以参考笔者这篇文章BootLoader的理解与实现。 STM32的跳转代码如下所示: u32 …

MATLAB - 评估拟合优度、评价拟合效果

系列文章目录 文章目录 系列文章目录前言一、如何评估拟合优度二、拟合优度统计2.1 SSE - 误差引起的平方和2.2 R 平方2.3 自由度调整 R 平方2.4 均方根误差 三、MATLAB - 评估曲线拟合度3.1 加载数据并拟合多项式曲线3.2 绘制拟合方程、数据、残差和预测范围图3.3 评估指定点3…

C++学习笔记之五(String类)

C 前言getlinelength, sizec_strappend, inserterasefindsubstrisspace, isdigit 前言 C是兼容C语言的,所以C的字符串自然继承C语言的一切字符串,但它也衍生出属于自己的字符串类,即String类。String更像是一个容器,但它与容器还…