二叉树_堆(下卷)

前言

接前面两篇的内容,接着往下讲二叉树_堆相关的内容。

正文

那么,回到冒泡排序与堆排序的比较。

我们知道冒泡排序的时间复杂度为 O ( N 2 ) O(N^2) O(N2),这个效率是不太好的。

那么,我们的堆排序的时间复杂度如何呢?

由于堆排序中我们使用到向下和向上调整,所以我们要先看看这两个算法的时间复杂度。

我们先看向上调整,主要看的是最多循环次数,如果我们的二叉树有k层,最大结点数为n,我们已经知道根据二叉树的性质: 2 k − 1 = n 2^k-1=n 2k1=n; k = l o g 2 ( n + 1 ) k=log_2(n+1) k=log2(n+1)

我们的向上调整的最差情况是和层次有关的。所以最后我们的向上调整算法的时间复杂度就为 O ( l o g n ) O(logn) O(logn)

而在这里我们循环n次向上调整,所以堆排序中建堆这一步的时间复杂度为 O ( n l o g n ) O(nlogn) O(nlogn)

我们再看后面这一步的时间复杂度。很明显,我们得看向下调整的时间复杂度。

因为向下调整也是和层次有关,我们可以粗估时间复杂度也为 O ( l o g n ) O(logn) O(logn)

那么最后我们的堆排序的时间复杂度为 O ( n l o g n ) O(nlogn) O(nlogn)+ O ( l o g n ) O(logn) O(logn),因为取的是对结果影响最大的那个,所以堆排序最后我们粗估的时间复杂度就为 O ( n l o g n ) O(nlogn) O(nlogn)

建堆的时间复杂度到底是不是 O ( n l o g n ) O(nlogn) O(nlogn),有待考证。

可以看看上面不同复杂度对比的图,发现冒泡排序的效率是比堆排序差很多的。

但是,我们仔细分析一下向上调整的时间复杂度,发现并不是我们刚才说的这么简单,因为我们的n在变化的过程中,需要交换的次数也是变化的。

在具体分析向上调整算法建堆的时间复杂度之前,我们先来说一个东西:这个是我们的向上调整算法建堆,其实我们还可以由向下调整方法来建堆。


向下调整算法建堆

(以大堆为例)

我们还是从堆顶也就是数组最前面的数据开始调整,要将堆顶的数据向下调整意味着下面的数据必须是有效的大堆。

所以我们遇到这样一个问题,为了将17向下调整,得保证它的子树是大堆;而我们要向下调整孩子结点20时,得保证20的子树是大堆……

那么我们可以改变一下思路,从最后一个结点的父节点开始向下调整,大的往上放建大堆。

i就是我们目前要向下调整的下标,i首先从最后一个结点的父节点开始;调整完后i–来到20的位置,向下调整后再次i–来到了17的位置,向下调整,这里会调整两层。最后我们就得到了一个大堆。

所以我们其实是从子树开始调整,然后保证堆顶的子树为堆后再将其进行向下调整。

代码:

可以看到,我们的大堆就成功建成了。

这就是我们的向下调整算法建堆。

可以看到向上调整算法建堆时我们就是从头(第一个数据)开始,而向下调整算法建堆我们则是从尾开始(最后一个结点的父节点)。


向上调整算法建堆VS向下调整算法建堆

这两种建堆算法,哪一种的时间复杂度更好呢?

我们需要数学推理。

向下调整算法建堆的时间复杂度推理

(我们只看到h-1层为止,因为最后一层不需要向下调整;h代表的是总层数;需要移动的层数是最坏情况的移动层数)

如图,要计算移动的次数是由结点的数量和移动的层次共同决定的,我们在二叉树的性质中可以得知每一层的最大节点数(每一层的节点数要移动的层数是不同的所以我们要分开去看),而层数我们也是可以知道的。

我们时间复杂度计算的是最坏的情况,所以我们可以这样计算需要移动的总步数: 每层节点个数 × 向下调整次数 每层节点个数×向下调整次数 每层节点个数×向下调整次数,最后加在一起。

然后我们通过错位相减,化简,再通过二叉树性质,代入可以得到 T ( n ) = n − l o g 2 ( n + 1 ) T(n)=n-log_2(n+1) T(n)=nlog2(n+1)。我们知道时间复杂度最后取对结果影响最大的那个,所以向下调整算法建堆我们最后得到的时间复杂度为 O ( n ) O(n) O(n)

(详细推理见下图)

用我们刚才乍一看的方法,外层循环大概为O(n),内层的AdjustDown方法根据二叉树的性质: 2 k − 1 = n 2^k-1=n 2k1=n; k = l o g 2 ( n + 1 ) k=log_2(n+1) k=log2(n+1),为O(logn),所以我们推测为O(nlogn),但实际上根据数学推导却是O(n)。

可以看到,我们如果乍一看,其实错误地算大了许多。

向上调整算法建堆的时间复杂度推理

同样的,因为是最坏情况,我们同样是计算每层的节点个数×每层结点要移动的层数,最后相加。

根节点无需向上调整,从第二层开始调整。

最后同样是错位相减、化简,利用性质替换,我们得到向上调整算法建堆的时间复杂度为 O ( n ∗ l o g 2 n ) O(n*log_2n) O(nlog2n)

(详细推理)

我们可以看出,对于向上调整算法建堆来说,越往下结点数越多,需要移动的层次也越多;向下调整算法建堆则越往上虽然要移动层次越多,但是节点数却越少。

移动层数越多×节点数越多,显然要比移动层次越多×节点数越少来得多。

所以我们凭借这个规律我们其实也可以就看出向下调整算法建堆的时间复杂度应该是更低的。

所以,无论是从时间复杂度的结果还是从这个规律来看,向下调整算法建堆的时间复杂度是更好的


过了这么久我们再说回堆排序,所以比较好的堆排序方法就是使用向下调整算法建堆加上循环将堆顶数据与当前的最后一个数据交换。

我们可以知道堆排序的时间复杂度就为向下调整算法建堆的O(n),加上后一个循环中用到向下调整方法复杂度为O(logn),所以整个循环复杂度为O(nlogn),O(n)+O(nlogn),取大的那个,所以堆排序的时间复杂度为O(n*logn)。

到此,本文结束,祝阅读愉快O(∩_∩)O

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

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

相关文章

017、Vue动态tag标签

文章目录 1、先看效果2、代码 1、先看效果 2、代码 <template><div class "tags"><el-tag size"medium"closable v-for"item,index in tags":key"item.path":effect"item.title$route.name?dark:plain"cl…

数据结构 - AVL树

文章目录 一、AVL树的介绍二、AVL树的实现1、基本框架2、查找3、插入4、删除5、测试6、总代码 三、AVL树的性能 一、AVL树的介绍 1、概念 AVL树&#xff08;Adelson-Velsky and Landis Tree&#xff09;是一种自平衡的二叉搜索树。它得名于其发明者G. M. Adelson-Velsky和E. M…

Vue 状态管理 Vue CLI

Vue 状态管理 & Vue CLI 1、状态管理2、集中状态管理2.1 Vuex2.1.1 Vuex核心概念2.1.2 Vuex Store实例2.1.3 Vuex Getter2.1.4 Vuex Mutation2.1.4 Vuex Actions2.1.4 Vuex Module 2.2 Pinia2.2.1功能增强 3、Vuex 实现原理4、Pinia 实现原理5、CLI5.1 实现 1、状态管理 将…

【CG】计算机图形学(Computer Graphics)基础(其贰)

0 学习视频 B站GAMES101-现代计算机图形学入门-闫令琪 ※ 接上文【CG】计算机图形学&#xff08;Computer Graphics&#xff09;基础&#xff08;其壹&#xff09; 7 光线追踪 7.1 为什么需要光线追踪&#xff1f; 光栅化无法妥善处理全局效果 &#xff08;软&#xff09;阴…

一天搞定React(5)——ReactRouter(下)【已完结】

Hello&#xff01;大家好&#xff0c;今天带来的是React前端JS库的学习&#xff0c;课程来自黑马的往期课程&#xff0c;具体连接地址我也没有找到&#xff0c;大家可以广搜巡查一下&#xff0c;但是总体来说&#xff0c;这套课程教学质量非常高&#xff0c;每个知识点都有一个…

MATLAB基础:函数与函数控制语句

今天我们继续学习Matlab中函数相关知识。 API的查询和调用 help 命令是最基本的查询方法&#xff0c;可查询所有目录、指定目录、命令、函数。 我们直接点击帮助菜单即可查询所需的API函数。 lookfor 关键字用于搜索相关的命令和函数。 如&#xff0c;我们输入lookfor inpu…

开源物联网网关ThingsBoard IoT Gateway

前几天测试了Neuron&#xff0c;这是一个令人印象深刻的平台&#xff0c;不过它不能算是完全免费的平台&#xff0c;因为它还是有商业许可要求的&#xff0c;挺贵的&#xff0c;大几万的&#xff0c;而且它有走向闭源的趋势。所以也在寻找它的替代方案。 今天看到一个ThingsBo…

Django项目中报错:django.template.exceptions.TemplateDoesNotExist: index.html

访问127.0.0.1&#xff1a;8000访问出错 查看报错原因 到Django项目当中找到settings.py&#xff0c;找到TEMPLATES中的DIRS: 添加如下代码&#xff0c;并导入OS模块&#xff1a; "DIRS": [os.path.join(BASE_DIR,templates)] 再次访问IP地址&#xff1a;

C++(入门1)

C参考文档 Reference - C Reference C 参考手册 - cppreference.com cppreference.com 第一个C程序 #include<stdio.h> int main() {printf("Hello C\n");return 0; }由上述代码可知C是兼容C语言 第一个C标准程序 #include<iostream> using names…

【机器学习】智驭未来:机器学习如何重塑制造业的转型与升级

&#x1f4dd;个人主页&#x1f339;&#xff1a;Eternity._ &#x1f339;&#x1f339;期待您的关注 &#x1f339;&#x1f339; ❀目录 &#x1f50d;1. 引言&#x1f4d2;2. 机器学习重塑制造业生产流程&#x1f338;预测性维护&#xff1a;减少停机时间&#xff0c;提高设…

实现共模噪声电流相互抵消的方法

共模传导路径中噪声电流相互抵消&#xff0c;从而使总的共模电流减小&#xff0c; 终达到降噪的目的。目前为实现共模噪声电流相互抵消&#xff0c;主要是采用动点电容抵消法。 动点电容抵消法原理 动点电容抵消法就是选取合适的动点&#xff0c;添加原副边跨接电容&#xff0c…

黑马头条Day10-定时计算热点文章、xxl-job

一、今日内容 1. 需求分析 目前实现的思路&#xff1a;从数据库直接按照发布时间倒序查询 问题&#xff1a; 如果访问量比较大&#xff0c;直接查询数据库&#xff0c;压力较大新发布的文章会展示在前面&#xff0c;并不是热点文章 2. 实现思路 解决方案&#xff1a;把热点…

CCS(Code Composer Studio 10.4.0)编译软件中文乱码怎么解决

如果是所有文件都出现了中文乱码这时建议直接在窗口首选项中修改&#xff1a;选择"Window" -> "Preferences"&#xff0c;找到"General" -> "Workspace"&#xff0c;将"Text file encoding"选项设置为"Other&quo…

深度解析Linux-C——函数和内存管理

目录 函数指针&#xff1a; 指针函数&#xff1a; 参数为指针的函数&#xff1a; 参数为数组的函数&#xff1a; C语言内存管理 stdlib.h头文件常用函数介绍 1、局部变量 2、全局变量 3、 堆空间变量 4、静态变量 5、常量 函数指针&#xff1a; 指向函数的指针&#…

Linux文件与相关函数的知识点3

main函数参数 int main(int argc,char *argv[]) { return 0; } C语言规定了main函数的参数只能有两个&#xff0c;一个是argc,一个是argv并且&#xff0c;argc只能是整数&#xff0c;第二个必须是指向字符 串的指针数组。 argc: 参数表示命令行中参数的个数&#xff0…

Java实现七大排序(二)

一.交换排序 1.冒泡排序 这个太经典了&#xff0c;每个学编程都绕不开的。原理跟选择排序差不多&#xff0c;不过冒泡排序是直接交换。 public static void bubbleSort(int[] array){for (int i 0; i < array.length - 1; i) {for (int j 0; j < array.length-1-i; j…

域内攻击手法——AS-REP Roasting攻击和Kerberoasting攻击

一、AS-REP Roasting攻击 1、AS-REP Roasting攻击原理 AS-REP Roasting是一种对用户账户进行离线爆破的攻击方式。但是该攻击方式使用上比较受限&#xff0c;因为其需要用户账户设置不要求Kerberos 预身份验证选项&#xff0c;而该选项默认是没有勾选的。Kerberos 预身份验证…

20240727 每日AI必读资讯

&#x1f310;OpenAI向Google宣战&#xff0c;重磅推出AI搜索引擎SearchGPT &#xff01; - 将 AI 与实时网络信息结合 提供生成式UI结果 - SearchGPT 结合网络最新信息可以直接回答问题&#xff0c;同时注明相关来源链接。 - 还可以像与人对话一样提出后续问题&#xff0c;…

进程概念(三)----- fork 初识

目录 前言1. pid && ppid2. forka. 为什么 fork 要给子进程返回 0&#xff0c; 给父进程返回子进程的 pid &#xff1f;b. 一个函数是如何做到两次的&#xff1f;c. fork 函数在干什么&#xff1f;d. 一个变量怎么做到拥有不同的内容的&#xff1f;e. 拓展&#xff1a;…

小红书电商首提“生活方式电商”定义,个性化需求也能做成好生意

近日&#xff0c;小红书发布COO柯南与经济学者薛兆丰的对谈视频。对谈中柯南首次对外定义&#xff0c;小红书电商是“生活方式电商”。 柯南表示&#xff0c;生活方式电商是让用户在小红书买到的&#xff0c;不仅是好产品&#xff0c;也是一种向往的生活。 随着生活方式的多元…