堆的应用(堆排序、TOP - K问题)

news2024/10/5 11:04:10

前言

🍎 时间复杂度:

🥝 堆排序的最坏时间复杂度为 :O(n*lg(n))

🥝 TOP - K问题的最坏时间复杂度为:O(n*lg(k))

    🍁前面我们学习了二叉树、以及堆的结构,也用顺序表的结构成功的把堆的结构一步一步的敲出来了。IT公司的吉祥“树” 二叉树-(堆)C语言创建_硕硕C语言的博客-CSDN博客(里面有一些树的基础知识,没有了解过的可以看一看,顺便来个三连应该不过分吧🥰)
,下面我将带领着大家来了解一下堆有什么应用、怎么用、用这个有什么好处。

堆排序

        🚩堆排序即利用堆的思想来进行排序,总共分为两个步骤:

1. 建堆

🔴升序:建大堆
🔴降序:建小堆

 2. 利用堆删除思想来进行排序

💧 建堆和堆删除中都用到了向下调整,因此掌握了向下调整,就可以完成堆排序。

思路:

⭕1.首先将待排序的数组构造成一个大根堆,此时,整个数组的最大值就是堆结构的顶端

⭕2.将顶端的数与末尾的数交换,此时,末尾的数为最大值,剩余待排序数组个数为n-1

⭕3.将剩余的n-1个数再构造成大根堆,再将顶端数与n-1位置的数交换,如此反复执行,便能得到有序数组

最详细的堆排序---排序算法,思路清晰动图讲解,五分钟搞懂!_Steve_hanhaiLong的博客-CSDN博客_堆排序

python-列表排序_QFIUNE的博客-CSDN博客_python列表排序

3. 代码: 

    //堆排序
    public static void heapSort(int[] arr) {
        //构造大根堆
        heapInsert(arr);
        int size = arr.length;
        while (size > 1) {
            //固定最大值
            swap(arr, 0, size - 1);
            size--;
            //构造大根堆
            heapify(arr, 0, size);
 
        }
 
    }
 
    //构造大根堆(通过新插入的数上升)
    public static void heapInsert(int[] arr) {
        for (int i = 0; i < arr.length; i++) {
            //当前插入的索引
            int currentIndex = i;
            //父结点索引
            int fatherIndex = (currentIndex - 1) / 2;
            //如果当前插入的值大于其父结点的值,则交换值,并且将索引指向父结点
            //然后继续和上面的父结点值比较,直到不大于父结点,则退出循环
            while (arr[currentIndex] > arr[fatherIndex]) {
                //交换当前结点与父结点的值
                swap(arr, currentIndex, fatherIndex);
                //将当前索引指向父索引
                currentIndex = fatherIndex;
                //重新计算当前索引的父索引
                fatherIndex = (currentIndex - 1) / 2;
            }
        }
    }
    //将剩余的数构造成大根堆(通过顶端的数下降)
    public static void heapify(int[] arr, int index, int size) {
        int left = 2 * index + 1;
        int right = 2 * index + 2;
        while (left < size) {
            int largestIndex;
            //判断孩子中较大的值的索引(要确保右孩子在size范围之内)
            if (arr[left] < arr[right] && right < size) {
                largestIndex = right;
            } else {
                largestIndex = left;
            }
            //比较父结点的值与孩子中较大的值,并确定最大值的索引
            if (arr[index] > arr[largestIndex]) {
                largestIndex = index;
            }
            //如果父结点索引是最大值的索引,那已经是大根堆了,则退出循环
            if (index == largestIndex) {
                break;
            }
            //父结点不是最大值,与孩子中较大的值交换
            swap(arr, largestIndex, index);
            //将索引指向孩子中较大的值的索引
            index = largestIndex;
            //重新计算交换之后的孩子的索引
            left = 2 * index + 1;
            right = 2 * index + 2;
        }
 
    }
    //交换数组中两个元素的值
    public static void swap(int[] arr, int i, int j) {
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }

 TOP - K问题

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

1. 用数据集合中前K个元素来建堆

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

🚨🚨注意:只找到TopK,不排序TopK。

 2. 用剩余的N-K个元素依次与堆顶元素来比较,不满足则替换堆顶元素

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

图解:( 找前K大的数据 )😍

还是老套路上图解释(这里以找前K大的数据为例子)

        🍟1.  先用前k个元素生成一个小顶堆,这个小顶堆用于存储,当前最大的k个元素。

       🍟 2. 接着,从第k+1个元素开始扫描,和堆顶(堆中最小的元素)比较,如果被扫描的元素大于堆顶,则替换堆顶的元素,并调整堆,以保证堆内的k个元素,总是当前最大的k个元素。

        🍟3. 扫描完所有n-k个元素,最终堆中的k个元素,就是前K大的数据。

时间复杂度

🚩 TOP - K问题的时间复杂度为:O(n*lg(k))

🚩 堆排序的最坏时间复杂度为 :O(n*lg(n))

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

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

相关文章

【uni-app】使用外部组件不显示报错组件未找到解决方案

文章目录 前言一、问题描述二、温馨提示总结 前言 大家好&#xff0c;今天和大家分享一下uni-app使用外部组件不显示报错的一个解决方案&#xff0c;希望能够帮助到大家。 一、问题描述 我在使用uni-app在开发项目时引入了一个外部的组件库&#xff0c;刚开始引入的时候还是…

【复习笔记】FreeRTOS(二)创建和删除任务

本文是FreeRTOS复习笔记的第二节&#xff0c;创建和删除任务&#xff0c;使用的开发板是stm32f407VET6&#xff0c;创建两个任务&#xff0c;task1负责闪烁LED&#xff0c;task2负责按键控制&#xff0c;当按键按下时task1停止执行&#xff0c;任务的状态显示到TFT显示屏和串口…

【数据库系统及应用】— 日志、故障恢复、事务、并发控制、调度、检查点

日志文件是用于记录__________。 A、数据操作 B、程序运行过程 C、程序执行结果 D、对数据的所有更新操作 下列说法正确的是__________。 A、事务故障可以通过运行日志进行恢复 B、介质故障只需将备份恢复到系统中即可实现正确性 C、检查点是指检查发生故障并进行恢复的时刻点…

MySQL 对日期使用 DATE_FORMAT()函数

文章目录 DATE_FORMAT()函数显示今天是星期几只显示年月显示当前时间的分钟数和秒数 DATE_FORMAT()函数 前面使用日期时间函数&#xff0c;获取到的要么是 yyyy-mm-dd 形式的日期&#xff0c;要么是 hh:MM:ss 形式的时间&#xff0c;或者是 yyyy-mm-dd hh:mm:ss 形式的日期及时…

论文解读 | ICRA2022:用深度贝叶斯算法来估计ICP的协方差

原创 | 文 BFT机器人 01 研究背景 在点云处理中&#xff0c;ICP算法是一种常用的点云配准方法&#xff0c;通过将两个或多个点云对齐&#xff0c;可以进行后续的建模、识别和跟踪等处理。 然而&#xff0c;在ICP算法中&#xff0c;协方差估计起着非常重要的作用&#xff0c;它…

网络安全基础免杀

1. 会话提升的几种方式2. armitage的熟悉3. handler生成监听器的方法4. 防止会话假死5. 控制台设置编码6. upx加壳7. msfvenom木马payload持久化8. msfvenom木马编码 正文 免杀1 1. 会话提升的几种方式 python -c "import pty;pty.spawn(/bin/bash);" 会话提升 se…

linuxOps基础_linux文件打包压缩与解压缩

linux打包压缩概念 默认情况下&#xff0c;Linux的压缩概念一次只能压缩一个文件。针对多文件或文件夹无法进行直接压缩。所以需要提前对多个文件或文件夹进行打包&#xff0c;这样才可以进行压缩操作。 打包 1.txt 5MB 2.txt 10MB 3.txt 15MB1.txt 2.txt 3.txt 打包…

为kong网关添加key-auth插件实现安全认证

官方指导文档&#xff1a;https://docs.konghq.com/gateway/latest/get-started/key-authentication/ 一、新建一个用户 这里我们新建一个usernameluka的用户 [rootmin ~]# curl -i -X POST http://localhost:8001/consumers/ \ > --data usernameluka HTTP/1.1 201 Cr…

JavaEE HTTP状态码 HTTP数据报的构造

HTTP状态码HTTP数据报的构造 文章目录 JavaEE & HTTP状态码 & HTTP数据报的构造1. HTTP状态码1.1 200 - OK1.2 404 - Not Found1.3 403 - Forbidden1.4 500 - Internal Server Error1.5 504 - Gateway Timeout1.6 302/301 重定向 2. 构造HTTP请求2.1 浏览器搜索栏输入u…

聚焦2023北京安博会,超高清安防应用将成潮流

&#xff08;1&#xff09;2023北京安博会 中国安全防范产品行业协会主办并承办的第十六届&#xff08;2023&#xff09;中国国际社会公共安全产品博览会&#xff08;Security China 2023&#xff09;&#xff0c;将于2023年6月7&#xff5e;10日在北京首钢会展中心开幕。安博…

面试阿里测开岗失败后,被面试官在朋友圈吐槽了......

前一阵子有个徒弟向我诉苦&#xff0c;说自己在参加某大厂测试面试的时候被面试官怼得哑口无言&#xff0c;场面让他一度十分尴尬 印象最深的就是下面几个问题&#xff1a; 根据你以前的工作经验和学习到的测试技术&#xff0c;说说你对质量保证的理解&#xff1f; 非关系型…

Jenkins+JMeter实现自动化,性能压测玩转CICD!

目录 前言&#xff1a; 准备工作 编写Jenkinsfile 编写JMeter脚本 编写 Dockerfile 总结 前言&#xff1a; 性能压测是应用程序开发中不可或缺的一环。它通过模拟应用程序在真实环境下的负载情况&#xff0c;从而检测系统在高负载下的性能表现。而随着依托云架构部署业务的不…

2022年长三角高校数学建模竞赛B题齿轮箱故障诊断解题全过程文档及程序

2022年长三角高校数学建模竞赛 B题 齿轮箱故障诊断 原题再现&#xff1a; 齿轮箱是用于增加输出扭矩或改变电机速度的机械装置&#xff0c;被广泛应用于如汽车、输送机、风机等机械设备中。它由两个或多个齿轮组成&#xff0c;其中一个齿轮由电机驱动。电机的轴连接到齿轮箱的…

大数据 Ranger2.1.0 适配 Kafka3.4.0

Ranger2.1.0 适配 Kafka3.4.0 官方说明POM代码说明 根据官方说明Kafka3.0以上版本将会被替换权限认证方式&#xff0c;包括 类和方法 的变换&#xff0c;所以需要对ranger中继承 kafka 的实现中&#xff0c;修改相应的逻辑 官方说明 Kafka3.0以上版本将会被替换权限认证方式&a…

vue项目瘦身

如图 项目中node_modules包已占用十几G&#xff0c;我也是发现我的磁盘空间缩小的超级快&#xff0c;因为好几个项目&#xff0c;甚至有的项目包已经占了50多G&#xff0c;这都得益于上一个刚走了的laji npm install -g depcheck 一旦安装了depCheck&#xff0c;您可以在命令行…

通过 Github workflows CI/CD 自动化部署 Github Pages hugo 免费博客

通过 Github workflows CI/CD 自动化部署 Github Pages hugo 免费博客 文章博客地址&#xff1a;https://blog.taoluyuan.com/posts/github-workflows/ Github Workflows 介绍 GitHub Actions 介绍 GitHub 文档&#xff1a;https://docs.github.com/zh/actions/learn-githu…

相机的畸变矫正与opencv代码说明

相机的畸变矫正与opencv代码说明 简介鱼眼模型的畸变校正针孔模型的畸变校正 简介 图像算法中会经常用到摄像机的畸变校正&#xff0c;有必要总结分析OpenCV中畸变校正方法&#xff0c;其中包括普通针孔相机模型和鱼眼相机模型fisheye两种畸变校正方法。普通相机模型畸变校正函…

机器人专业讲师与科技的转型思考

2023年以前&#xff0c;编程需要学习各种语法&#xff0c;现在只需要提示词。 未来还需要编程老师吗&#xff1f;需求一定越来越少。 “ Prompting TurtleSim from ChatGPT ” https://github.com/mhubii/chatgpt_turtlesim The demo lets ChatGPT call into ROS services …

左孩子右兄弟路径之谜

题目 对于一棵多叉树&#xff0c;我们可以通过 “左孩子右兄弟” 表示法&#xff0c;将其转化成一棵二叉树。 如果我们认为每个结点的子结点是无序的&#xff0c;那么得到的二叉树可能不唯一。 换句话说&#xff0c;每个结点可以选任意子结点作为左孩子&#xff0c;并按任意顺序…

开源版社区团购系统源码 含小程序完整前后端+搭建教程+私有化部署

分享一个社区团购系统源码&#xff0c;源码开源可自由二开&#xff0c;含小程序完整前后端和详细的搭建教程&#xff0c;可私有化部署终身使用&#xff0c;功能界面diy团长供应商拼团秒杀优惠券菜谱积分群接龙充值预售配送等功能。 系统功能一览&#xff1a; 1、商品&#xf…