java堆排序

news2024/11/17 11:49:01

 

堆排序是最基本的排序算法,简单来说就是把一堆数据(数组)分成两个相等的部分,其中一个部分作为数组的开头,另一个部分作为数组的结尾。之后在对这两个相等的部分进行比较,如果在比较之后发现这个数组中有一项小于等于另外一项,则将这两个相等的部分合并起来,并将它重新放回数组中间。如此进行,直到最后完成排序为止。 堆排序算法有如下优点: 1、递归调用 2、速度快 3、对所有元素都进行一次比较 4、易于理解,容易实现 5、可以进行并行计算 6、内存消耗低 7、支持并发执行 8、程序优化难度低

  • 1.算法思想

    在堆中进行排序时,我们可以将一个数组分成两部分,分别称为堆头和堆尾,堆头可以是数组的某个元素,也可以是数组的任意位置。当对这个数组进行排序时,我们需要将堆头的元素取出,并将它放到数组的最后一位。 例如对于一个数组:[0,1],其中0是该数组的最小元素。当我们对这个数组进行排序时,首先需要对[0]这个元素进行比较,如果这个元素小于[0]时则将它取出并放到堆头;然后将[1]元素也取出并放到堆头;最后将[1]元素和[0]元素比较,如果其中一个大于另一个则将它们合并起来重新放到数组的末尾。 需要注意的是,如果我们没有在堆中找到任何元素(假设我们已经找到了),那么堆中的所有元素都是相同的。当我们发现数组中有一个元素比其他所有元素大时,则说明这个元素是比其他所有元素小的。此时可以把这个数组重新放回堆头中。

  • 2.参数设置

    堆排序的参数是 arr (numbers_list),用来存储堆中最大的元素。这个参数会在数组大小固定时自动调整,而且堆中最大的元素和数组长度一定,所以每次操作时都会动态调整。 具体来讲就是: 在第一次排序时,堆中最大的元素就是当前堆的第一个元素,那么当数组长度为O (1)时,就要将当前堆中最大的元素移动到第二个位置。 当堆中元素较多时,可以使用循环对其进行合并,循环结束后会将当前堆中所有元素重新排序。对于多个元素来说,可能会有更好的处理方式。 例如在第一次排序时,发现数组长度为2的元素已经小于等于数组长度为3的元素,但是这个数组长度却比3长很多,那么这时就需要将数组中小于3的元素移动到2到3之间。如果不移动,则会导致两个不相等的数据放在一块,因此需要移动数组长度为2的元素才能使两个相等。 如果将数组长度为3的元素移动到2到3之间后发现仍然小于3,则需要将数组中小于3的元素移动到2到3之间。 也可以使用“/”将堆中最大的元素移动到其他位置。具体用法可以参考 python中“。 replace”函数

  • 3.堆的创建

    堆的创建有两种方式,第一种是使用链表来存储堆,第二种是使用栈来存储堆。使用链表的方式需要一个链表,而使用栈的方式则需要一个栈。 如果你想创建一个有序的堆,那么就需要先将数组分割成两个部分,即两个元素相等的部分,然后将它们放入到一个栈中。此时该栈的地址为0x00010,即“第一个元素”对应的位置。之后再对这两个元素进行比较,如果它们相等的话,则将它们放在同一个栈顶;如果有一项小于另一项,则将它们移到栈底;如此进行下去即可完成排序。 但是如果你想在一个有序的堆中存储堆元素,那么你就需要创建一个链表来存储堆。链表的结构如下: 我们可以看到,在堆中创建了两个部分,这两个部分分别是第一个元素和第二个元素。但是这两个元素都是不相等的。也就是说我们在创建堆时,必须先将第一个元素和第二个元素都放入到一个链表中去。 如果我们只有两个元素需要进行比较的话,那么就可以直接将它们放到同一个链表中去,但是如果我们要将两个元素都放入到同一个链表中去的话,那么就必须先对这两个元素进行比较。如果比较之后发现第一个元素小于第二个元素的话,则将它们移到链表的顶层;如果比较之后发现第二个元素大于第一个元素的话,则将它们移到栈底。

  • 4.堆的大小

    堆是一个临时数组,其大小在堆的生命周期内保持不变,其大小由两部分组成: 堆的大小可以用下标(或堆中元素的数量)表示: 为了不产生重复元素,最小的堆包含一个元素总数,其下标是一个常数(例如8)。 如果当前堆已经大于最小的堆,则新生成一个新的堆,并将老的堆放到新生成的堆中。如此类推。 在每次迭代时,最小堆中包含之前数组中最大元素。在每个迭代后,新生成的堆将元素总数减1。如果当前数组中的所有元素都小于最小堆中最大元素,则将这些元素重新放回原来的位置。在每个迭代后,都会有一个新的堆(与前一个相比)。

  • 5.比较

    堆排序的时间复杂度为O (1),因此它也是时间复杂度为O (n)的算法。但是堆排序对于元素较多的情况,执行速度会比较慢,可以通过二分法来减少堆排序的时间复杂度。 如果堆排序在执行过程中,发现有数组长度小于数组最大值时,可以直接把数组最大值部分移动到数组长度最小的位置上,然后再重新进行堆排序。因为在堆排序过程中,每次都要移动元素到数组中间位置,所以时间复杂度为O (n)。

  • 6.输出结果

    堆排序是基于循环的,循环的次数也是从0开始,一直到堆顶。我们知道一个有序的数组只有一个元素,而堆排序正好能把所有元素都进行一次比较,所以我们在进行堆排序的时候只需要把需要比较的元素放入到堆中,再重复以上操作即可。 那么堆排序适合多少个数组呢?这个问题也不是很好回答,因为不同的算法适用于不同的情况。如果我们需要对一堆元素进行比较的话,我们可以采用归并排序或者直接找出第一个元素。而如果我们想要找到数组中的最大值或者最小值的话,我们则可以采用冒泡排序或选择排序来完成。 以上内容为个人理解,有错误的地方还望指正!

  • 以下是Java实现的堆排序代码:
    1. 递归实现
    ```java
    public static void heapSort(int[] arr) {
    if (arr == null || arr.length == 0) {
    return;
    }
    int len = arr.length;
    // 构建最大堆
    buildMaxHeap(arr, len);
    // 交换堆顶元素和末尾元素,然后重新调整堆
    for (int i = len - 1; i > 0; i--) {
    swap(arr, 0, i);
    len--;
    heapify(arr, 0, len);
    }
    }
    private static void buildMaxHeap(int[] arr, int len) {
    for (int i = len / 2; i >= 0; i--) {
    heapify(arr, i, len);
    }
    }
    private static void heapify(int[] arr, int i, int len) {
    int left = 2 * i + 1;
    int right = 2 * i + 2;
    int largest = i;
    if (left < len && arr[left] > arr[largest]) {
    largest = left;
    }
    if (right < len && arr[right] > arr[largest]) {
    largest = right;
    }
    if (largest != i) {
    swap(arr, i, largest);
    heapify(arr, largest, len);
    }
    }
    private static void swap(int[] arr, int i, int j) {
    int temp = arr[i];
    arr[i] = arr[j];
    arr[j] = temp;
    }
    ```
    2. 非递归实现
    ```java
    public static void heapSort(int[] arr) {
    if (arr == null || arr.length == 0) {
    return;
    }
    int len = arr.length;
    // 构建最大堆
    for (int i = len / 2; i >= 0; i--) {
    heapify(arr, i, len);
    }
    // 交换堆顶元素和末尾元素,然后重新调整堆
    for (int i = len - 1; i > 0; i--) {
    swap(arr, 0, i);
    int j = 0;
    int k = 2 * j + 1;
    while (k < i) {
    if (k + 1 < i && arr[k + 1] > arr[k]) {
    k++;
    }
    if (arr[k] > arr[j]) {
    swap(arr, k, j);
    j = k;
    k = 2 * j + 1;
    } else {
    break;
    }
    }
    }
    }
    private static void heapify(int[] arr, int i, int len) {
    int left = 2 * i + 1;
    int right = 2 * i + 2;
    int largest = i;
    if (left < len && arr[left] > arr[largest]) {
    largest = left;
    }
    if (right < len && arr[right] > arr[largest]) {
    largest = right;
    }
    if (largest != i) {
    swap(arr, i, largest);
    heapify(arr, largest, len);
    }
    }
    private static void swap(int[] arr, int i, int j) {
    int temp = arr[i];
    arr[i] = arr[j];
    arr[j] = temp;
    }
    ```

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

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

相关文章

读懂什么是RDMA

一.什么是RDMA 1.RDMA主要体现 2.如何理解RDMA和TCP技术的区别&#xff1f; 3.使用RDMA的好处包括&#xff1a; 二.什么是RoCE&#xff1f; 1. RDMA协议包含: Infiniband&#xff08;IB&#xff09; 2. 为什么RoCE是目前主流的RDMA协议&#xff1f; …

GhostNet

文章目录 相关文章一、轻量化网络结构1. 分组卷积2. 深度可分离卷积 二、GhostNet1. 动机2. Ghost Module 相关文章 https://blog.csdn.net/search_129_hr/article/details/130280697 https://blog.csdn.net/c2250645962/article/details/104601305 一、轻量化网络结构 目的…

信息收集(一)域名信息收集

前言 信息收集也叫做资产收集。信息收集是渗透测试的前期主要工作&#xff0c;是非常重要的环节&#xff0c;收集足够多的信息才能方便接下来的测试&#xff0c;信息收集主要是收集网站的域名信息、子域名信息、目标网站信息、目标网站真实IP、敏感/目录文件、开放端口和中间件…

052:cesium加载网格地图

第052个 点击查看专栏目录 本示例的目的是介绍如何在vue+cesium中加载grid地图。一个 ImageryProvider,它在每个具有可控背景和发光的图块上绘制线框网格。 可能对自定义渲染效果或调试地形很有用。 直接复制下面的 vue+cesium源代码,操作2分钟即可运行实现效果. 文章目录 …

redis 教程 6(Redis 的Pipeline , Lua)

Redis 的Pipeline, Lua PipelinePipeline简介为什么需要PipelinePipeline 性能测试与原生批量命令对比 LuaLua 与事物Lua 的用法Redis 如何管理Lua脚本 Pipeline Pipeline简介 Pipeline&#xff08;流水线&#xff09; 能够将一组redis命令进行组装&#xff0c; 通过一次RTT&…

fmriprep2

一. sub-subXXX文件夹 sub-subXXX.html 二. sub-subXXX文件夹 sub-sub097 / anat / figures / func / log / anat / anat文件夹内文件比较多&#xff0c;文件命名规则遵守BIDS要求( https://bids-specification.readthedocs.io/en/stable/05-derivatives/01-introduction.ht…

【国内chatgpt使用方法合集】

写在前面 Hello大家好&#xff0c; 我是【麟-小白】&#xff0c;一位软件工程专业的学生&#xff0c;喜好计算机知识。希望大家能够一起学习进步呀&#xff01;本人是一名在读大学生&#xff0c;专业水平有限&#xff0c;如发现错误或不足之处&#xff0c;请多多指正&#xff0…

2023_4_23_VS下Release怎么打断点进行debug

&#x1f37f;*★,*:.☆(&#xffe3;▽&#xffe3;)/$:*.★* &#x1f37f; &#x1f4a5;&#x1f4a5;&#x1f4a5;欢迎来到&#x1f91e;汤姆&#x1f91e;的csdn博文&#x1f4a5;&#x1f4a5;&#x1f4a5; &#x1f49f;&#x1f49f;喜欢的朋友可以关注一下&#xf…

MySQL——流程控制函数

在 MySQL 中&#xff0c;流程控制函数是指可以控制存储过程&#xff08;stored procedure&#xff09;或函数&#xff08;function&#xff09;中执行流程的语句。以下是几个常用的流程控制函数&#xff1a; 1. IF函数 实现IF……ELSE……的效果。 # 如果expr1为true&#x…

深入探究java中的 xxxable和xxxator

前言 相信有一定工作经验的朋友,都见过或者用过xxxable和xxxator ,比如常见的Comparable和Comparator, 还有还有常见并且容易迷糊的Iterable和Iterator, 看这名字,前两个是和比较相关的, 后两个是和迭代相关. 但是命名如此相似的接口, 又有何区别呢?各自的用途又是什么呢? 今…

详解车载设备FOTA测试

作者 | 李伟 上海控安安全测评部总监 来源 | 鉴源实验室 引言&#xff1a;上一篇文章我们以车载Tbox为例介绍了相关的性能测试&#xff08;车载TBOX嵌入式设备软件的性能测试&#xff09;&#xff0c;本篇我们介绍另外一个重要功能的专项测试&#xff1a;OTA&#xff08;Over…

MySQL安装及卸载

安装 mysql现在安装的是5.7.mysql的安装方式有两种: 一种是exe方式 另外一种解压版 这次就使用解压版安装 解压缩到非中文目录 编写配置文件 1) 在安装目录下新建my.ini的配置文件 打开文件后缀和隐藏文件显示 2) 新建文件内编写内容 [Client] port 3306 [mysqld] #设置330…

【移植Ardupilot的日志记录方法到linux上】

移植Ardupilot的日志记录方法到linux上 说明日志结构组成日志写入操作预定义日志项运行时添加日志项的方法 单例测试编译方法查看数据其他 说明 采用二进制文件记录&#xff0c;可在mission planer查看 支持所有数据类型记录精巧移植方便可直接在地面站绘制曲线查看可导出生成…

觉非科技发布:基于BEV的数据闭环融合智驾解决方案

2023年上海车展期间&#xff0c;觉非科技基于BEV的数据闭环融合智能驾驶解决方案正式发布。 该方案可通过量产车BEV的实时感知结果&#xff0c;提供完整的城市Map-lite及Map-free数据闭环融合解决方案&#xff0c;并满足城市NOA、记忆通勤/泊车以及感知大模型训练的需要。 车…

OSPF基础配置实验

目录 一、实验要求与拓扑结构 1、实验要求 2、提前规划好的网段以及拓扑结构如下图 二、实验步骤 1、给各个路由器的每个接口配ip 2、运行ospf协议并划分区域 一、实验要求与拓扑结构 1、实验要求 首先划分区域&#xff0c;蓝色区域为Area 0&#xff0c;黄色区域为Area…

MyBatis(十五)MyBatis的逆向工程

前言、 所谓的逆向工程是&#xff1a;根据数据库表逆向生成Java的pojo类&#xff0c;SqlMapper.xml文件&#xff0c;以及Mapper接口类等。 要完成这个工作&#xff0c;需要借助别人写好的逆向工程插件。 思考&#xff1a;使用这个插件的话&#xff0c;需要给这个插件配置哪些…

基于 TensorRT 使用 python 进行推理优化

文章大纲 简介TensorRT 简介构建测试的conda 环境注意事项TensorRT 安装参考文献与学习路径简介 TensorRT 简介 TensorRT是NVIDIA推出的一个高性能的深度学习推理框架,可以让深度学习模型在NVIDIA GPU上实现低延迟,高吞吐量的部署。TensorRT支持Caffe,TensorFlow,Mxnet,P…

【Python】实战:生成无关联单选问卷 csv《压疮风险评估表》

目录 一、适用场景 二、业务需求 三、Python 文件 &#xff08;1&#xff09;创建文件 &#xff08;2&#xff09;代码示例 四、csv 文件 一、适用场景 实战场景&#xff1a; 问卷全部为单选题问卷问题全部为必填问题之间无关联关系每个问题的答案分数不同根据问卷全部问…

FPGA基于XDMA实现PCIE X8采集AD7606数据 提供工程源码和QT上位机程序和技术支持

1、前言 PCIE&#xff08;PCI Express&#xff09;采用了目前业内流行的点对点串行连接&#xff0c;比起 PCI 以及更早期的计算机总线的共享并行架构&#xff0c;每个设备都有自己的专用连接&#xff0c;不需要向整个总线请求带宽&#xff0c;而且可以把数据传输率提高到一个很…

倍数+路径之谜

倍数 :用户登录https://www.lanqiao.cn/problems/583/learning/?page5&first_category_id1&sortstudents_count 题目描述 本题为填空题&#xff0c;只需要算出结果后&#xff0c;在代码中使用输出语句将所填结果输出即可。 请问在 1 到 2020 中&#xff0c;有多少个…