十大排序之堆排序(详解)

news/2024/5/19 5:47:30 标签: java, 算法, 排序算法, 堆排序

文章目录

  • 🐒个人主页
  • 🏅算法思维框架
    • 📖前言:
  • 🎀堆排序 时间复杂度O(n*logn)
      • 🎇1. 算法步骤思想
      • 🎇2、动画演示
      • 🎇3.代码实现

🐒个人主页

🏅算法思维框架

📖前言:

本篇博客主要以介绍十大排序算法中的堆排序,有详细的图解、动画演示、良好的代码注释,帮助加深对这些算法的理解,进行查漏补缺~

🎀堆排序 时间复杂度O(n*logn)

堆排序(Heapsort) 是指利用堆这种数据结构所设计的一种排序算法。堆是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。堆排序可以说是一种利用堆的概念来排序的选择排序。分为两种方法:
大顶堆:每个节点的值都大于或等于其子节点的值,在堆排序算法中用于升序排列;
小顶堆:每个节点的值都小于或等于其子节点的值,在堆排序算法中用于降序排列; 堆排序的平均时间复杂度为 Ο(nlogn)。

有好多人都说堆排序代码有点复杂但是它的思路其实是最好理解的!他的思路是将大根堆顶的最大值元素放到数组没有排序区间的末尾,然后对没有排序的区间重新变成大根堆,直到没有排序的区间中只剩一个元素,就排好序了。
难的无非是不会将一个数组变成堆heapify,也不会取出堆顶元素后(删除操作(下沉操作)),再将其变成堆
堆排序详细图解

🎇1. 算法步骤思想

  1. 创建一个堆 H[0……n-1] ;【heapify()操作----->时间复杂度O(n)】
  2. 把堆首(最大值)和堆尾互换;【交换数组中的堆顶与数组未排序区间的末尾元素】
  3. 调用swim()方法----->时间复杂度O(logn),使除过堆尾元素的树满足最大堆的性质;【对没有排序的区间进行下沉操作,重新生成堆】
  4. 重复步骤 2,直到堆中只有一个元素。

🎇2、动画演示

在这里插入图片描述
在这里插入图片描述

🎇3.代码实现

java">public int[] sort(int[] nums) {
        if(nums==null||nums.length<2){
            return nums;
        }
        //思路:【堆排序】:先将nums[]构建成大根堆heapify()操作,
        // 再将堆顶元素与未排序区间的末尾元素进行交换,对此时的堆顶元素进行【无序区间】的下沉操作,重复上述操作....直至数组有序
        heapify(nums);//【将nums[]数组变成堆】
        //进行排序
        for (int i = nums.length-1; i >0; i--) {
            //交换
            int temp=nums[i];
            nums[i]=nums[0];
            nums[0]=temp;
            //对根节点进下沉操作,让没有排序的区间重新变成堆
            swim(nums,0,i);
        }
        return nums;
    }
    //写两个辅助方法:获取父亲节点下标,获取左孩子节点下标
    private int getParentIndex(int childIndex){
        return (childIndex-1)/2;
    }
    private int getLeftChildIndex(int parentIndex){
        return 2*parentIndex+1;
    }
    private void heapify(int[] nums){//【将nums[]数组变成堆】
        //思路:拿到数组最后一个元素的父亲节点下标,直到根节点,依次进行下沉操作
        int lastParentIndex=getParentIndex(nums.length-1);
        for (int i = lastParentIndex; i >=0 ; i--) {
            swim(nums,i,nums.length);
        }
    }

    /**
     * 下沉操作
     * @param nums 进行下沉操作的数组
     * @param index  需要进行下沉操作的节点
     * @param length 进行下沉操作的区间长度
     */
    private void swim(int[] nums,int index,int length){
        //下沉思路:将目标值rootVal与当前节点index的左右孩子最大优先级进行比较:
        // 1.如果rootVal<孩子优先级,孩子优先级覆盖当前父亲节点index,index索引最大优先级的孩子,重新找孩子进行比较
        // 2.如果rootVal>=孩子优先级,找到了break,将当前节点nums[index]=rootVal
        //3.如果找到头都没有找到,将当前节点nums[index]=rootVal            【情况2、3可合并处理】
        int rootVal=nums[index];//寄存将要下沉节点的值
        int leftIndex=getLeftChildIndex(index);//获取当前节点的左孩子
        int maxChildPiroirtyIndex=leftIndex;//【默认左孩子为孩子的最大优先级,原因堆是一棵完全二叉树...】
        while (leftIndex<length){//左孩子存在
            int rightIndex=leftIndex+1;//右孩子下标
            if(rightIndex<length&&nums[leftIndex]<nums[rightIndex]){//左孩子存在且左孩子优先级<右孩子优先级
                maxChildPiroirtyIndex=rightIndex;
            }
            //进行优先级的比较
            if(rootVal<nums[maxChildPiroirtyIndex]){
                nums[index]=nums[maxChildPiroirtyIndex];//覆盖父节点
                //更新索引指向
                index=maxChildPiroirtyIndex;
                leftIndex=getLeftChildIndex(index);
                maxChildPiroirtyIndex=leftIndex;
            }else {
                break;
            }
        }
        nums[index]=rootVal;//插入目标值
    }

http://www.niftyadmin.cn/n/5213503.html

相关文章

Android设计模式--外观模式

弈之为术&#xff0c;在人自悟 一&#xff0c;定义 外观模式要求一个子系统的外部与其内部的通信必须通过一个统一的对象进行。提供一个高层次的接口&#xff0c;使得子系统更易于使用。 外观模式在开发中的使用频率是非常高的&#xff0c;尤其是在第三方的SDK里面&#xff0…

【linux挂载windows,密码含特殊字符,使用证书方式挂载】

1、设置Windows端共享文件目录 暂定设置共享目录为为&#xff1a;D:\shared 2、Linux客户端挂载 安装samba服务 查看是否安装&#xff1a;rpm -qa | grep samba samba4-libs-4.0.0-58.el6.rc4.x86_64 samba4-4.0.0-58.el6.rc4.x86_64 samba4-client-4.0.0-58.el6.rc4.x86_64 s…

为什么别人能做好CSGO游戏搬砖,而你不能?

CSGO搬砖日常出货更新 做Steam游戏搬砖的门槛很低&#xff0c;以至于这两年不断有小白涌入市场&#xff0c;想要在饰品市场中分一杯羹。这个项目是很简单&#xff0c;但想要站稳脚跟&#xff0c;有稳定收入的第一步就得搞清楚项目逻辑。 首先你得搞清楚&#xff0c;steam搬砖盈…

各种工具的快捷键或命令

前言 这里就存放自己存有的一些小工具的地址以及工具的命令。 正文 零、各种小工具 1、wizTree:磁盘分析工具-分析磁盘的文件夹存储 2、稻壳阅读器&#xff1a;有黑色背景 3、youtube 视频下载&#xff1a;https://zh.savefrom.net/226/ 4、视频录制&#xff1a;Bandica…

分享一个鬼~

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站。 先看效果&#xff1a; 上源码&#xff1a; import GUI from "https://cdn.jsdelivr.net/npm/lil-gui0.18.2/esm"const canv…

基于springboot实现高校食堂移动预约点餐系统【项目源码】计算机毕业设计

基于springboot实现高校食堂移动预约点餐系统演示 Java语言简介 Java是由SUN公司推出&#xff0c;该公司于2010年被oracle公司收购。Java本是印度尼西亚的一个叫做爪洼岛的英文名称&#xff0c;也因此得来java是一杯正冒着热气咖啡的标识。Java语言在移动互联网的大背景下具备…

浅谈现代化城市建设中智慧消防的研究与应用

安科瑞 华楠 【摘要】随着城市现代化发展&#xff0c;城市居住密度愈来愈大&#xff0c;城市建筑结构复杂多样化&#xff0c;高层建筑火灾发生率在不断地升高。对现代化城市面临的消防问题展开讨论&#xff0c;针对智慧消防在现代化城市建设中的现状进行了分析&#xff0c;并提…