【数据结构】二叉树-堆(top-k问题,堆排序,时间复杂度)

 🌈个人主页:秦jh__https://blog.csdn.net/qinjh_?spm=1010.2135.3001.5343
🔥 系列专栏:《数据结构》https://blog.csdn.net/qinjh_/category_12536791.html?spm=1001.2014.3001.5482

​​

目录

堆排序

第一种

 ​编辑

第二种

 TOP-K问题

建堆的时间复杂度

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

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

 补充


 

   前言

    💬 hello! 各位铁子们大家好哇。

             今日更新了堆排序,top-k问题和时间复杂度的内容
    🎉 欢迎大家关注🔍点赞👍收藏⭐️留言📝

 

堆排序

第一种

 

假如左右子树都是小堆,我们只需要进行向下调整建堆即可。

下方是建大堆: 

 

思路分析:这里的向上和向下调整都是建大堆的。如果我们想进行升序排序,我们就得先建大堆。因为小堆的同一层中,无法进行比较。 接着,交换根结点和最后一个结点,这时就已经将最大的数排在末尾了。然后再从根结点向下调整建大堆,这时第二大的数就排在了根结点,再swap进行交换。end--表示不再对已排好的数进行操作。如此循环,即可进行升序。

总结:如果是升序,就要建大堆。如果是降序,就要建小堆。 堆排序的本质是选择排序。

        建堆的时间复杂度:N*logN

        选数的时间复杂度:(N-1)*logN

第二种

当左右子树不一定都是小堆时,我们就要进行从下往上的向下调整建堆

方法:从倒数第一个非叶子开始(即最后一个节点的父亲)。9,2,8,5不用调,我们从1开始,1和9满足小堆。接着往前一位数到2,此时也满足小堆。继续往前到6,1和5比,1更小,所以1和6交换。接着来到4,交换后的1和2,1更小,4就和1交换

此方法的时间复杂度是O(N),并且此方式只需要一个向下调整,不需要多写一个向上调整函数。

 

建小堆时,我们就会得到降序的数据。 

 

 TOP-K问题

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

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

2.用剩余的N-K个元素依次与堆顶元素来比较,不满足则替换堆顶元素
将剩余N-K个元素依次与堆顶元素比完之后,堆中剩余的K个元素就是所求的前K个最小或者最大的元素。

举例如下:

   

我们先生成一千万个随机数。

topk函数如下:

void PrintTopK(const char* file, int k)
{FILE* fout = fopen(file, "r");if (fout == NULL){perror("fopen fail");return;}//建一个k个数的小堆int* minheap = (int*)malloc(sizeof(int) * k);if (minheap == NULL){perror("malloc fail");return;}//读取前k个,建小堆for (int i = 0; i < k;i++){fscanf(fout, "%d", &minheap[i]);AdjustUp(minheap, i);}int x = 0;while (fscanf(fout, "%d", &x) != EOF){if (x > minheap[0]){minheap[0] = x;AdjustDown(minheap, k, 0);}}for (int i = 0; i < k; i++){printf("%d ", minheap[i]);}printf("\n");fclose(fout);
}

 我们先建立k个数的小堆,并将前k个数放进去。接着从第k+1开始的数开始与根结点比较,如果大于,就替换,然后进行向下调整,恢复成堆的形式。直到所有的数都比较完,我们就能找出前k个最大或最小的数了。

最后的运行结果如下:

  

建堆的时间复杂度

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

这里举例向下调整建堆的时间复杂度:

因为第h层是叶,就不需要向下移动了。具体计算过程如下图,因为是等差*等比,所以采用错位相减法进行计算。

因为最后的结果中的h是树的高度,不方便看出时间复杂度,替换成N(节点的个数)

 

最终,时间复杂度是O(N)。

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

 

 

上方是求向上调整建堆时间复杂度的计算过程,原理与向下调整的一样。

最终的时间复杂度是:O(N*logN)

 补充

上方的过程的时间复杂度是O(N*logN),他跟上方的向上调整建堆相似,都是多*多,少*少的关系。因为最后一层有2^(h-1)个节点,每次交换后,最坏情况要向下调整(h-1)层,即多*多。第1层有一个节点,向下调整0层,即少*少。

 

 

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

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

相关文章

【不用找素材】ECS 游戏Demo制作教程(3) 1.17

一、生成墓碑 新建脚本如下&#xff1a; using Unity.Entities; using Unity.Mathematics;namespace ECSdemo {public struct GraveyardRandom : IComponentData{public Random Value;}}扩充GraveyardMono如下&#xff1a; using Unity.Entities; using Unity.Mathematics; …

使用arcgis pro是类似的控件样式 WPF

1.资源加载 <controls:ProWindow.Resources><ResourceDictionary><ResourceDictionary.MergedDictionaries><extensions:DesignOnlyResourceDictionary Source"pack://application:,,,/ArcGIS.Desktop.Framework;component\Themes\Default.xaml&quo…

Unreal Engine(UE5)中构建离线地图服务

1. 首先需要用到3个软件&#xff0c;Unreal Engine&#xff0c;gis office 和 bigemap离线服务器 Unreal Engine下载地址:点击前往下载页面 Gis office下载地址:点击前往下载页面 Bigemap离线服务器 下载地址: 点击前往下载页面 Unreal Engine用于数字孪生项目开发&#x…

Qt绘画的使用

1. 绘图 绘图组件&#xff1a; 1、绘画对象 2、绘画位置 3、绘画工具 4、绘画时机 绘画时机&#xff1a; 当整个窗口或窗口的一部分需要重新绘制时&#xff0c;会调用绘制事件处理函数 void QWidget::paintEvent(QPaintEvent *event) 绘画对象&#xff1a; QPainter类&#xff…

axios的原理及源码解析

面试官&#xff1a;你了解axios的原理吗&#xff1f;有看过它的源码吗&#xff1f; 一、axios的使用 关于axios的基本使用&#xff0c;上篇文章已经有所涉及&#xff0c;这里再稍微回顾下&#xff1a; 发送请求 import axios from axios;axios(config) // 直接传入配置 axio…

龙腾荆楚 | 软件供应链安全检测中心落地襄阳

1月16日&#xff0c;襄阳市东津新区“园区提质、企业满园”行动暨2024年东津云谷首月重大项目集中签约活动圆满完成&#xff0c;开源网安城市级项目再下一城&#xff0c;分别与襄阳市政府、高校、国投签订战略合作协议&#xff0c;推动荆楚地区数字政府、数字经济、数字社会、数…

阿里云 linux Centos7 安装 Miniconda3 + 创建Python环境

1.下载miniconda &#xff08;1&#xff09;法一&#xff1a;可以去下载清华源的miniconda镜像源&#xff0c;选择自己需要的版本&#xff0c;然后上传到Linux服务器上&#xff0c;linux上使用请选择linux版本&#xff0c;如下&#xff1a; &#xff08;2&#xff09;法二&…

vsc 不适用插件来更改背景图片

我之前看的教程都是推荐用的插件来修改 vsc 的背景&#xff0c;我感觉不稳定&#xff0c;不如自己来弄一个 那我们该如何操作呢&#xff0c;第一步先找到我们 vsc 的文件夹 依次进入 resources\app\out\vs\workbench 这个路径 就会看到 我们再新建一个文件夹 image&#xff…

银河麒麟操作系统 v10 中离线安装 Docker

银河麒麟操作系统 v10 中离线安装 Docker 1. 查看系统版本2. 查看 Linux 内核版本&#xff08;3.10以上&#xff09;3. 查看 iptabls 版本&#xff08;1.4以上&#xff09;4. 判断处理器架构5. 离线下载 Docker 安装包6. 移动解压出来的二进制文件到 /usr/bin 目录中7. 配置 Do…

AM5-DB低压备自投装置在河北冠益荣信科技公司洞庭变电站工程中的应用

摘 要&#xff1a;随着电力需求的不断增加&#xff0c;电力系统供电可靠性要求越来越高&#xff0c;许多供电系统已具备两回或多回供电线路。备用电源自动投入装置可以有效提高供电的可靠性&#xff0c;该类装置能够在工作电源因故障断开后&#xff0c;自动且迅速地将备用电源投…

Arm Generic Interrupt Controller v3 and v4(GICv3v4)学习(一)

提示 该博客主要为个人学习&#xff0c;通过阅读官网手册整理而来&#xff08;个人觉得阅读官网的英文文档非常有助于理解各个IP特性&#xff09;。若有不对之处请参考参考文档&#xff0c;以官网参考文档为准。 Arm Generic Interrupt Controller v3 and v4学习一共分为三章&…

Elasticsearch各种文档操作

本文来记录下Elasticsearch各种文档操作 文章目录 初始化文档数据查询所有文档匹配查询文档关键字精确查询文档多关键字精确查询文档字段匹配查询文档指定查询字段查询文档 初始化文档数据 在进行各种文档操作之前&#xff0c;我们先进行初始化文档数据的工作 查询所有文档 在 …

C++核心编程之通过类和对象的思想对文件进行操作

目录 ​​​​​​​一、文件操作 1. 文件类型分类&#xff1a; 2. 操作文件的三大类 二、文本文件 1.写文件 2.读文件 三、二进制文件 1.写二进制文件 2.读二进制文件 一、文件操作 程序运行时产生的数据都属于临时数据,程序一旦运行结束都会被释放 通过文件可以将…

【LV12 DAY17-18 中断处理】

GPX1_1是外部中断9 EINT9 查询可知其中断ID是57 所以需要进行人为修正lr的地址 sub lr&#xff0c;lr&#xff0c;#4 //iqr异常处理程序 irq_handler: //IRQ异常后LR保存的地址是被IRQ打断指令的下一条再下一条指令的地址&#xff0c;所以我们需要人为进行修正一下sub LR,L…

【北亚企安数据恢复】RAIDZ多块磁盘离线导致服务器崩溃的数据恢复案例

服务器数据恢复环境&#xff1a; ORACLE SUN ZFS某型号存储&#xff0c;共40块磁盘组建存储池&#xff0c;其中的36块磁盘分为三组&#xff0c;每组12块&#xff0c;单个组使用ZFS特有的RAIDZ管理所有磁盘&#xff0c;RAIDZ级别为2&#xff1b;另外的4块磁盘作为全局热备。存储…

DDDDDD

DDD 1、团队边界&#xff1a; 导购&#xff1a;负责用户的搜索和下单&#xff0c; 供应链负责机票的覆盖&#xff0c; 自营本身是一个商家&#xff08;一个企业&#xff09;&#xff0c;对供应链进行加工&#xff0c;在导购进行销售&#xff0c;主要负责收益、履约交付、财务方…

强化学习与监督学习【区别】

强化学习很强大&#xff0c;但是有大多数场景毫无使用它的必要&#xff0c;监督学习就够了。下面分析强化学习和监督学习的区别和强化学习有前景的应用。 目录 决策是否改变环境当前奖励还是长线回报总结 决策是否改变环境 监督学习假设模型的决策不会影响环境&#xff0c;而强…

【代码随想录07】344.反转字符串 541. 反转字符串II 05.替换空格 151.翻转字符串里的单词 55. 右旋转字符串

目录 344. 反转字符串题目描述做题思路参考代码 541. 反转字符串 II题目描述参考代码 05. 替换数字题目描述参考代码 151. 反转字符串中的单词题目描述参考代码 55. 右旋转字符串题目描述参考代码 344. 反转字符串 题目描述 编写一个函数&#xff0c;其作用是将输入的字符串反…

mac vscode latex实用

网上有教程怎么在vscode里安装macTex以及插件&#xff0c;然后就可以在latex里写代码了&#xff0c;这里需要修改的是对应的json文件&#xff0c;输入command P,可以看到最近打开的json设置文件&#xff0c;结果如下 然后设置这个json文件&#xff0c;我的json文件设置如下 …

three.js 点按钮,相机飞行靠近观察设备

效果&#xff1a; 代码&#xff1a; <template><div><el-container><el-main><div class"box-card-left"><div id"threejs" style"border: 1px solid red"></div><div class"box-right&quo…