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

这篇具有很好参考价值的文章主要介绍了堆的应用(堆排序、TOP - K问题)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

🍎 时间复杂度:

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

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

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

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

堆排序

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

1. 建堆

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

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

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

思路:

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

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

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

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

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

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个元素。

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

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

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

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

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

时间复杂度

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

🚩 堆排序的最坏时间复杂度为 :O(n*lg(n))文章来源地址https://www.toymoban.com/news/detail-464610.html

到了这里,关于堆的应用(堆排序、TOP - K问题)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • 堆的应用:Top-K问题

    堆的应用:Top-K问题

    朋友们、伙计们,我们又见面了,本期来给大家解读一下堆的应用--Top-K问题的相关知识点,如果看完之后对你有一定的启发,那么请留下你的三连,祝大家心想事成! 数据结构与算法专栏 :数据结构与算法 个  人  主  页 :stackY、 C 语 言 专 栏 :C语言:从入门到精通 目

    2024年02月07日
    浏览(14)
  • 堆的实现,画图和代码分析建堆,堆排序,时间复杂度以及TOP-K问题

    堆的实现,画图和代码分析建堆,堆排序,时间复杂度以及TOP-K问题

    如果有一个关键码的集合K = {k 0 ,k 1 ,k 2 ,…,k n-1 },把它的所有元素按 完全二叉树 的顺序存储方式存储在一个一维数组中,并满足:k i =k 2*i+1 且 =k 2*i+2 (k i =k 2*i+1 且 =k 2*i+2 ) i = 0,1,2…,则称为小堆(或大堆)。将根节点最大的堆叫做最大堆或大根堆,根节点最小的堆叫

    2024年02月04日
    浏览(11)
  • 【数据结构】堆的应用+TOP-K问题+二叉树遍历

    【数据结构】堆的应用+TOP-K问题+二叉树遍历

    欢迎来到我的: 世界 希望作者的文章对你有所帮助,有不足的地方还请指正,大家一起学习交流 ! 该篇文章写到主要是:堆排序、 TOP-K问题、二叉树链式结构的实现、二叉树的遍历等等;如果有朋友还不太了解堆以及二叉树可以翻看我的上一篇博客:堆和二叉树的概念; 最

    2024年02月07日
    浏览(10)
  • Java 数据结构篇-实现堆的核心方法与堆的应用(实现 TOP-K 问题:最小 k 个数)

    Java 数据结构篇-实现堆的核心方法与堆的应用(实现 TOP-K 问题:最小 k 个数)

    🔥博客主页: 【 小扳_-CSDN博客】 ❤感谢大家点赞👍收藏⭐评论✍      文章目录         1.0 堆的说明         2.0 堆的成员变量及其构造方法          3.0 实现堆的核心方法         3.1 实现堆的核心方法 - 获取堆顶元素 peek()         3.2 实现堆的核心方法 - 下潜 do

    2024年02月04日
    浏览(7)
  • 堆的实际应用(topk问题以及堆排序)

    堆的实际应用(topk问题以及堆排序)

    目录 前言: 一:解决topk问题 二:堆排序 【1】第一种方法(很少用) 【2】第二种方法(很实用) 上一次我们进行了二叉树的初步介绍并实现了堆的基本功能,但堆的作用并不是存储数据, 它可以用来解决topk问题 ( 求一组数据较大或者较小的前k个 )以及 对数据进行排序 。 附上一

    2024年02月01日
    浏览(10)
  • 数据结构:堆的应用(堆排序和topk问题)

    数据结构:堆的应用(堆排序和topk问题)

    个人主页 : 个人主页 个人专栏 : 《数据结构》 《C语言》 堆排序即是 先将数据建堆,再利用堆删除的思想来排序。 将待排序数组建堆 将堆顶数据与数组尾部数据交换 调整新的堆顶数据,使其保证堆的结构不变 重复2,3步直到堆中没有数据结束。 降序 建小堆 (父节点 小于

    2024年02月13日
    浏览(13)
  • 数据结构--堆的实现-大根堆/小根堆/堆排序/堆排序稳定性证明/TOP-K

    数据结构--堆的实现-大根堆/小根堆/堆排序/堆排序稳定性证明/TOP-K

            前言          逆水行舟,不进则退!!!                目录        认识堆        堆的创建         1,向下调整的方法建立堆         2,以向下调整的方式建立小根堆         3,向上调整的方式建堆        堆的插入        堆的删除              

    2024年02月04日
    浏览(12)
  • 【数据结构】堆的应用——Top-K

    目录 前言: 一、Top-K问题描述: 二、不同解决思路实现: ①.排序法: ②.直接建堆法: ③.K堆法 总结:         上篇文章我们学习了二叉树的顺序存储结构,并且对于实际使用中所常用的顺序存储结构——堆的各个接口进行实现。这篇文章我们将对堆的实际应用进行更加

    2024年02月16日
    浏览(15)
  • 数据结构:堆的三部曲(二)top K问题

    数据结构:堆的三部曲(二)top K问题

    top k问题解决的是获取前几个最值的问题。 我们知道 堆的功能主要是选数,选出最大值或者最小值 。那么我们每次获取堆顶元素后,再将剩余元素调整成堆,就可以选出次大的数,如果我们只想要前k个最大值或者最小值,就只需要获取堆顶元素k次,调整k次。比如王者荣耀

    2024年02月02日
    浏览(9)
  • 数据结构——堆的应用 堆排序详解

    数据结构——堆的应用 堆排序详解

    hello hello~ ,这里是大耳朵土土垚~💖💖 ,欢迎大家点赞🥳🥳关注💥💥收藏🌹🌹🌹 💥 个人主页:大耳朵土土垚的博客 💥 所属专栏:数据结构学习笔记 💥对于数据结构顺序表、链表、堆有疑问的都可以在上面数据结构的专栏进行学习哦~ 有问题可以写在评论区或者私信

    2024年03月11日
    浏览(13)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包