二叉树_堆(下卷)

前言

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

正文

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

我们知道冒泡排序的时间复杂度为 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://xiahunao.cn/news/3269889.html

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

相关文章

《数据结构:链表递归实现二叉树》

文章目录 一、链式结构二叉树二、链式二叉树的遍历1、遍历方式2、前序遍历3、中序遍历4、后序遍历 三、链式二叉树结点个数和高度等1、二叉树结点的个数2、二叉树叶子结点的个数3、第K层结点的个数4、树的深度5、找值所在的结点6、二叉树销毁 四、借助队列完成二叉树的操作1、队…

react.16+

1、函数式组件 在vite脚手架中执行&#xff1a; app.jsx: import { useState } from react import reactLogo from ./assets/react.svg import viteLogo from /vite.svg import ./App.cssfunction App() {console.log(this)return <h2>我是函数式组件</h2> }exp…

leetcode-104. 二叉树的最大深度

题目描述 给定一个二叉树 root &#xff0c;返回其最大深度。 二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。 示例 1&#xff1a; 输入&#xff1a;root [3,9,20,null,null,15,7] 输出&#xff1a;3示例 2&#xff1a; 输入&#xff1a;root [1,n…

全能数据分析工具:Tableau Desktop 2019 for Mac 中文激活版

Tableau Desktop 2019 一款专业的全能数据分析工具&#xff0c;可以让用户将海量数据导入并记性汇总&#xff0c;并且支持多种数据类型&#xff0c;比如像是编程常用的键值对、哈希MAP、JSON类型数据等&#xff0c;因此用户可以将很多常用数据库文件直接导入Tableau Desktop&am…

字符串的引入和注意事项

首先&#xff0c;他和整型一样————int data[ ]{1,2,3,4,5}; 和整型数组一个道理————char str[ ]{h,a,l,l,o}; 还可以直接表达成这样————char str[ ]"hallo";字符串变量&#xff0c;可以被修改 或者用另一种方式————char *p"hallo";字符…

C# 使用pythonnet 迁入 python 初始化错误解决办法

pythonnet 从 3.0 版本开始&#xff0c;必须设置Runtime.PythonDLL属性或环境变量 例如&#xff1a; string pathToVirtualEnv ".\\envs\\pythonnetTest"; Runtime.PythonDLL Path.Combine(pathToVirtualEnv, "python39.dll"); PythonEngine.PythonHom…

.Net 检验信息采集及管理系统LIS,成熟的医院实验室管理系统源码

检验管理系统LIS实现了检验信息电子化、检验信息管理自动化&#xff0c;具备与医嘱双向沟通、采用条码管理手段、财务自动计费、仪器双向控制等重要功能特点。其工作流程为通过门诊医生和住院工作站提出检验申请&#xff0c;生成相应患者的化验条码标签&#xff0c;在生成化验单…

计算机专业MEM工程管理硕士课程介绍

计算机专业MEM&#xff08;工程管理硕士&#xff09;的主要学习内容涵盖了工程技术、管理学和经济学等多个领域&#xff0c;特别是结合了计算机专业的特点&#xff0c;注重在项目管理、工程管理、信息系统管理等方面的培养。以下是对计算机专业MEM工程管理硕士主要学习课程的详…

leetcode105. 从前序与中序遍历序列构造二叉树,步骤详解附代码

leetcode105. 从前序与中序遍历序列构造二叉树 给定两个整数数组 preorder 和 inorder &#xff0c;其中 preorder 是二叉树的先序遍历&#xff0c; inorder 是同一棵树的中序遍历&#xff0c;请构造二叉树并返回其根节点。 示例 1: 输入: preorder [3,9,20,15,7], inorder…

ubuntu22.04单个网口两个IP

其中 4网段IP可用来上网&#xff0c;3 网段用来内网 界面显示: 配置文件&#xff1a; 01-network-manager-all.yaml 放在 /etc/netplan/ # Let NetworkManager manage all devices on this systemnetwork:version: 2renderer: networkdethernets:eth0:dhcp4: falsedhcp6: …

大学生暑期三下乡社会实践通讯稿怎样投稿?

在这个充满挑战与机遇的暑期,我有幸成为学院暑期三下乡社会实践活动的一员,并肩负起志愿服务团队向媒体投稿宣传报道的重任。起初,面对这项任务,我满怀激情与期待,以为只需凭借一腔热血和手中的笔,就能将实践的点点滴滴生动呈现给世人。然而,现实却给我上了一堂生动的课。 之初…

使用vscode连接开发机进行python debug

什么是debug&#xff1f; 当你刚开始学习Python编程时&#xff0c;可能会遇到代码不按预期运行的情况。这时&#xff0c;你就需要用到“debug”了。简单来说&#xff0c;“debug”就是能再程序中设置中断点并支持一行一行地运行代码&#xff0c;观测程序中变量的变化&#xff…

在线心里咨询系统的设计与实现2024(代码+论文+开题报告+ppt)

下载在最后 技术栈: vuemysqlspringboot 展示: 下载地址: https://download.csdn.net/download/hhtt19820919/89583101 备注: 运行有问题请私信我,私信按钮在文章左边)

鱼哥好书分享活动第28期:看完这篇《终端安全运营》终端安全企业基石,为你的终端安全保驾护航!

鱼哥好书分享活动第28期&#xff1a;看完这篇《终端安全运营》终端安全企业基石&#xff0c;为你的终端安全保驾护航&#xff01; 读者对象&#xff1a;主要内容&#xff1a;本书目录&#xff1a;了解更多&#xff1a;赠书抽奖规则: 在当前网络威胁日益复杂化的背景下&#xff…

nginx转发netty长链接(nginx负载tcp长链接配置)

首先要清楚一点&#xff0c;netty是长链接是tcp连接不同于http中负载在http中配置server监听。长连接需要开启nginx的stream模块(和http是并列关系) 安装nginx时注意开启stream&#xff0c;编译时加上参数 --with-stream &#xff08;其他参数根据自己所需来加&#xff09; …

基于Pytorch框架的深度学习densenet121神经网络鸟类行为识别分类系统源码

第一步&#xff1a;准备数据 5种鸟类行为数据&#xff1a;self.class_indict ["bowing_status", "grooming", "headdown", "vigilance_status", "walking"] &#xff0c;总共有23790张图片&#xff0c;每个文件夹单独放一…

Github个人网站搭建详细教程【Github+Jekyll模板】

文章目录 前言一、介绍1 Github Pages是什么2 静态网站生成工具3 Jekyll简介Jekyll 和 GitHub 的关系 4 Mac系统Jekyll的安装及使用安装Jekyll的简单使用 二、快速搭建第一个Github Pages网站三、静态网站模板——Chirpy1 个人定制 四、WordPress迁移到Github参考资料 前言 23…

Opencv学习项目4——手部跟踪

上一篇博客我们介绍了mediapipe库和对手部进行了检测&#xff0c;这次我们进行手部关键点的连线 代码实现 import cv2 import mediapipe as mpcap cv2.VideoCapture(1) mpHands mp.solutions.hands hands mpHands.Hands() mpDraw mp.solutions.drawing_utilswhile True:…

IDEA-安装插件 驼峰下划线转换

第一步&#xff1a;安装 file-settings-plugins-在marketplace搜索“CamelCase”-点击安装 第二步&#xff1a;设置 file-settings-editor-camel_case 第三步&#xff1a;使用 选中想转换的遍历 使用快捷键 Alt Shift U

Windows环境下安装docker、配置Ubuntu容器并使用vscode ssh连接到容器

目录 一、Windows环境下安装docker二、配置Ubuntu三、在容器中安装ssh服务参考文章 一、Windows环境下安装docker 在任务栏中搜索**“Windows功能”** -将适用于Linux的Windows子系统和虚拟机平台选上 然后按照提示重启电脑。然后开始安装WSL。通过cmd以管理员身份打开命令提…