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

2023-11-10

堆排序

同步微信公众号乐享Coding,欢迎你的关注!

介绍:利用这种数据结构而设计的一种排序算法,堆排序是一种选择排序,它的最坏,最好,平均时间复杂度均为O(nlogn),它是不稳定排序。

对于堆排序,难点在于二叉树的顺序数组储存到大顶堆(小顶堆)的转换。从数据存储来看,数组存储方式树的存储方式可以相互转换,即数组可以转换成树,树也可以转换成数组。我习惯于不空谈理论,拿实例讲解,以下将针对数组arr[1,2,5,4,3,7]进行大顶堆的数据结构转换。

如图:

堆是具有以下性质的完全二叉树:每个结点的值都大于或等于其左右孩子结点的值,称为大顶堆,每个结点的值都小于或等于其左右孩子结点的值,称为小顶堆

代码实现思路:

步骤一 构造初始堆。将给定无序序列构造成一个大顶堆(一般升序采用大顶堆,降序采用小顶堆)。

图解大顶堆详细思路:

  • 我们从最后一个非叶子结点开始(叶结点自然不用调整,第一个非叶子结点 arr.length/2-1=5/2-1=1,也就是下面的索引为2的结点),从右至左从下至上进行调整。

  • 由于[5,7]中7元素最大,5和7交换。

  • 最后一个非叶子结点索引减1,找到第二个非叶结点(索引1),由于[4,3,2]中4元素最大,2和4交换。

  • 非叶子结点索引减1,找到第三个非叶结点(索引0),由于[4,1,7]中7元素最大,1和7交换。

  • 这时,交换导致了子根[1,5]结构混乱,继续调整,[1,5]中5最大,交换1和5。

  • 此时,我们就将一个无序序列构造成了一个大顶堆。

步骤二 将堆顶元素与末尾元素进行交换,使末尾元素最大。然后继续调整堆,再将堆顶元素与末尾元素交换,得到第二大元素。如此反复进行交换、重建、交换。

最后,就实现了堆排序。

文章末尾将代码附上,如有不清楚的地方,可以Debug加深下理解!

   public static void heapSort(int[] arr) {
        //1.构建大顶堆
        for (int i = arr.length / 2 - 1; i >= 0; i--) {
            //从第一个非叶子结点从下至上,从右至左调整结构
            adjustHeap(arr, i, arr.length);
        }
        //然后继续调整堆,再将堆顶元素与末尾元素交换,得到第二大元素。如此反复进行交换、重建、交换。
        //2.调整堆结构+交换堆顶元素与末尾元素
        for (int j = arr.length - 1; j > 0; j--) {
            swap(arr, 0, j);//将堆顶元素与末尾元素进行交换
            adjustHeap(arr, 0, j);//重新对堆进行调整
        }
    }
    /**
     * 调整大顶堆(仅是调整过程,建立在大顶堆已构建的基础上, 也就是说只调用一次,并没有得到大顶堆)
     * 就是将arr[i] 的值放到本次 调整过程中适当的位置。
     * @param arr    : 数组
     * @param i      : 非叶子节点的索引
     * @param length : 对多少个元素进行调整,这个length是逐渐减少的..
     */
    public static void adjustHeap(int[] arr, int i, int length) {
        int temp = arr[i];//先取出当前元素i
        for (int k = i * 2 + 1; k < length; k = k * 2 + 1) {//从i结点的左子结点开始,也就是2*i+1处开始
            if (k + 1 < length && arr[k] < arr[k + 1]) {//如果左子结点小于右子结点,k指向右子结点
                k++;
            }
            if (arr[k] > temp) {//如果子节点大于父节点,将子节点值赋给父节点(不用进行交换)
                arr[i] = arr[k];//把较大的值,赋给当前节点
                i = k;//i 指向k,继续循环比较
            } else {
                break;
            }
        }
        arr[i] = temp;//将temp值放到最终的位置
    }
    public static void swap(int[] arr, int a, int b) {
        int temp = arr[a];
        arr[a] = arr[b];
        arr[b] = temp;
    }

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

最详细的堆排序---排序算法,思路清晰动图讲解,五分钟搞懂! 的相关文章

随机推荐

  • Flink分布式执行包括调度、通信机制、检查点

    Flink的分布式执行包括两个重要的进程 master和worker 执行Flink程序时 多个进程参与执行 即作业管理器 Job Manager 任务管理器 Task Manager 和作业客户端 Job Client Flink程序需要
  • 考研DS备考

    23考研算法复习 一 图论相关算法 1 拓扑排序 2 最小生成树 2 1 Prim算法朴素实现 2 2 最小生成树Kruskal实现 3 最短路 3 1朴素版Dijkstra 3 2Bellman ford 3 3Floyd 二 排序相关算
  • Python 快速获取文件夹中的所有文件名,并保存到txt文件中

    下面的代码可以读取文件夹中的所有文件名 并记录到txt文件中 可以应用到如深度学习制作数据集等场景中 usr bin env python encoding utf 8 import os img path images img list
  • Windows防火墙阻止了远程调试

    问题 当调试数据库里的存储过程时提示 Windows防火墙当前阻止了远程调试 当接着打开SQL Server的时候提示 远程过程调用失败 解决办法 1 当遇到远程过程调试失败
  • windows下查看GPU使用率

    进入C Program Files NVIDIA Corporation NVSMI 在此处打开cmd 输入nvidia smi 第一行Driver Version 表示驱动是385 54 第二行中 第一行表示GPU序号 名字 Persis
  • python作业题

    1 输入三个坐标表示三角形的三个顶点 计算三角形的面积 import math x1 y1 x2 y2 x3 y3 eval input x1 y1 x2 y2 x3 y3 如果不在一条直线上就构成了三角形 if x1 x2 y1 y2 x
  • GMM-HMM在语音识别中的应用

    1 语音识别系统的基本结构 2 涉及算法 3 GMM高斯混合模型 3 1高斯混合模型的基本概念 高斯混合模型是指具有如下形式的概率分布模型 p y k 1k k y k p y arrowvert theta sum k 1 k alpha
  • docker redis单例安装

    环境 windows docker desktop 版本 19 03 12 1 下载redis的docker镜像 docker pull redis 6 0 8 2 设置docker共享目录 docker中的共享目录 即能将宿主的文件同步到
  • Pandas

    文章目录 1 什么是Pandas 2 Pandas的数据结构 2 1 Series 2 1 1 Series的创建 2 1 2 Series的属性 2 2 DataFrame 2 2 1 DataFrame的创建 2 2 2 DataFra
  • 在linux上odoo搭建

    一 配置Postgresql数据库 1 安装Postgresql root runner home sg os apt get install postgresql 2 配置postgresql 拷贝 var lib postgresql
  • Centos7五步安装Docker并解决docker官方镜像无法访问问题

    根据官方文档 https docs docker com install linux docker ce centos 搭建docker 1 卸载docker旧版本 sudo yum remove docker docker client
  • C++实现——小孩分糖果问题

    include
  • el-dialog组件实现可以拖拽移动功能

    面向百度编程的小白最近遇到一个el dialog实现拖拽移动的需求 翻了翻饿了么官网发现el dialog并没有关于这一块的属性方法 所以与大家分享一下有关的方法 首先新建一个js文件 directive js文件 用于详情对话框可移动 i
  • python4行代码实现九九乘法表

    九九乘法表是python的循环嵌套 两次利用range 相乘并输出 for i in range 1 10 for j in range 1 i 1 print sx s s j i i j end print
  • QThread线程的运行和退出

    关于QT退出线程 一直迷迷糊糊的 凑活着能用就行 出了问题总觉得莫名其妙 现在静下心来总结一下 感谢 QThread的用法 开启与退出 Qt QThread 这是我 见过解析最全面的一片文章 线程运行有两种方式 include
  • Python图像处理

    1 图像平滑 图像平滑是指受传感器和大气等因素的影响 遥感图像上会出现某些亮度变化过大的区域 或出现一些亮点 也称噪声 这种为了抑制噪声 使图像亮度趋于平缓的处理方法就是图像平滑 图像平滑实际上是低通滤波 平滑过程会导致图像边缘模糊化 图像
  • 关于FlashDB的应用-GD32F450上

    一 介绍 1 FlashDB是什么 是用于嵌入式的数据库存储 2 FlashDB谁整出来的 是armink 朱天龙 3 FlashDB依赖于什么 片内或者片外的Flash存储 FAL 4 FAL什么 FAL Flash Abstractio
  • 制作搭建宠物商城小程序,打造便捷的宠物购物体验

    随着宠物市场的不断发展 宠物商城小程序成为了满足宠物爱好者需求的重要工具 在现代社会 宠物已经成为人们生活中不可或缺的一部分 作为宠物爱好者 我们对于宠物食品 用品 医疗保健品等需求日益增长 而宠物商城小程序则为我们提供了一个便捷高效的购物
  • 在Matlab2018b中配置MinGW-w64 C/C++ 编译器

    在Matlab2018b跑代码时 输入mex setup 报错 错误使用 mex 未找到支持的编译器 您可以安装免费提供的 MinGW w64 C C 编译器 在 https jmeubank github io tdm gcc artic
  • 最详细的堆排序---排序算法,思路清晰动图讲解,五分钟搞懂!

    堆排序 同步微信公众号乐享Coding 欢迎你的关注 介绍 利用堆这种数据结构而设计的一种排序算法 堆排序是一种选择排序 它的最坏 最好 平均时间复杂度均为O nlogn 它是不稳定排序 对于堆排序 难点在于二叉树的顺序数组储存到大顶堆 小