堆排序详细解读

 

简介

堆排序是一种基于二叉堆数据结构的排序算法,它的特点是不同于传统的比较排序算法,它是通过建立一个堆结构来实现的。堆排序分为两个阶段,首先建立堆,然后逐步将堆顶元素与堆的最后一个元素交换并调整堆,使得最大(或最小)元素逐步沉到堆的末尾,完成排序。

堆的概念

  • 堆是一种特殊的树状数据结构,其中每个节点的值大于等于(或小于等于)其子节点的值。是一个平衡二叉树。
  • 最大堆:每个节点的值都大于或等于其子节点的值。
  • 195fc9a703b24b02a65741cc5f2770c3.png
  • 最小堆:每个节点的值都小于或等于其子节点的值。

堆排序步骤

  1. 构建堆: 将待排序的数组构建成一个二叉堆。

    • 最大堆构建: 从数组的中间位置开始,从右至左,从下至上进行堆调整。
    • 最小堆构建: 从数组的中间位置开始,从右至左,从下至上进行堆调整。
  2. 堆排序: 通过反复将堆的根节点(最大或最小值)与堆的最后一个元素交换,并重新调整堆,实现排序。

    • 最大堆排序: 将堆顶元素与堆的最后一个元素交换,然后将堆的大小减1,并重新调整堆。
    • 最小堆排序: 类似于最大堆排序,但是每次选择堆中的最小元素。

堆排序的代码示例(最大堆排序)

public class HeapSort {public static void main(String[] args) {int[] arr = {3, 8, 2, 5, 1, 4, 7, 6};heapSort(arr);for (int i : arr) {System.out.print(i + " ");}}public static void heapSort(int[] arr) {for (int i = (arr.length -1)/ 2 ; i >= 0; i--) {adjustHeap(arr, i, arr.length);}int temp;for (int j = arr.length - 1; j > 0; j--) {temp = arr[j];arr[j] = arr[0];arr[0] = temp;adjustHeap(arr, 0, j);}}public static void adjustHeap(int[] arr, int i, int length) {int 父节点 = arr[i];for (int k = i * 2 + 1; k < length; k = k * 2 + 1) {if (k + 1 < length && arr[k] < arr[k + 1]) {k++;}//k左右孩子较大的一个if (arr[k] > 父节点) {arr[i] = arr[k];i = k;} else {break;}}arr[i] = 父节点;}}

 

 详细讲解

这段代码实现了堆排序(Heap Sort)算法。我将为你逐段解释代码的功能。

  1. 初始化数组:

int[] arr = {3, 8, 2, 5, 1, 4, 7, 6};

这行代码定义了一个整数数组 arr,并初始化了8个数值。
2. 调用堆排序方法

heapSort(arr);

 这行代码调用了 heapSort 方法,并将数组 arr 作为参数传递。
3. 打印排序后的数组:

for (int i : arr) {  System.out.print(i + " ");  
}

这段代码遍历数组 arr 并打印每个元素。此时,数组应该已经被排序,所以输出的应该是排序后的数组:1 2 3 4 5 6 7 8 。
4. 堆排序方法:
堆排序方法分为两个主要部分:建立最大堆和交换堆顶元素与最后一个元素,然后调整堆。 

* **建立最大堆**:  
```  
java`for (int i = (arr.length -1)/ 2 ; i >= 0; i--) {  adjustHeap(arr, i, arr.length);  
}`  
```  
这段循环遍历数组的索引,从 `(arr.length -1)/ 2` 到 0,并对每个索引调用 `adjustHeap` 方法来调整堆。  
* **交换和调整堆**:  
```  
java`for (int j = arr.length - 1; j > 0; j--) {  temp = arr[j];  arr[j] = arr[0];  arr[0] = temp;  adjustHeap(arr, 0, j);  
}`  
```  
这段循环每次从数组的末尾开始,将堆顶元素(最大值)与最后一个元素交换,然后重新调整堆。这样,最大的元素会逐渐移到数组的末尾。

5. 调整堆方法:
这个方法负责调整堆以满足最大堆的特性。如果父节点的值小于其子节点的值,那么就需要交换它们。这个方法会一直递归地检查和调整,直到满足最大堆的条件为止。

6.主类HeapSort:这是整个程序的容器,它包含 main 方法和其他辅助方法。

好的,我继续为您解释这段代码。

7.adjustHeap方法详解:

public static void adjustHeap(int[] arr, int i, int length) {  int 父节点 = arr[i]; // 获取当前节点的值,并将其称为父节点  for (int k = i * 2 + 1; k < length; k = k * 2 + 1) { // 循环遍历左孩子节点,右孩子节点  if (k + 1 < length && arr[k] < arr[k + 1]) { // 如果右孩子的值大于左孩子的值  k++; // 则将k移动到右孩子的位置  }  //k左右孩子较大的一个  if (arr[k] > 父节点) { // 如果当前节点大于父节点  arr[i] = arr[k]; // 用当前节点的值替换父节点的值  i = k; // 将i设置为当前节点的索引  } else {  break; // 如果当前节点不大于父节点,则跳出循环  }  }  arr[i] = 父节点; // 将父节点的值设置回父节点位置  
}

这段代码的主要目的是确保堆的属性在调用该方法后得到满足。它从给定的索引 i 开始,并确保该索引下的子节点是最大的。如果子节点的值小于父节点,则交换它们。这个过程会继续,直到满足堆的属性为止。

总结:这段代码实现了一个堆排序算法。它首先构建一个最大堆,然后通过交换堆顶元素与最后一个元素来排序数组。每次交换后,它都会重新调整堆以确保其属性得到满足。

 

 

 

 

 

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

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

相关文章

EM32DX-C2【C#】

1说明&#xff1a; 分布式io&#xff0c;CAN总线&#xff0c;C#上位机二次开发&#xff08;usb转CAN模块&#xff09; 2DI&#xff1a; 公共端是&#xff1a; 0V【GND】 X0~X15&#xff1a;自带24v 寄存器地址&#xff1a;0x6100-01 6100H DI输入寄存器 16-bit &#x…

ROS2 galactic生成的bag包里的MarkerArray在humble下播放不正常

近期发现ROS2 galactic下生成的bag包在humble下回放时使用rviz可视化&#xff0c;bag里的点云可以正常看到&#xff0c;但是使用Marker和MarkerArray画的box却死活看不到&#xff0c;感觉很纳闷&#xff0c;看网上有人报告说foxy下生成的bag包在galactic下播放会报SQL错误&…

Redis部署-哨兵模式

目录 redis sentinel相关名词 redis sentinel架构 故障转移流程 基于docker搭建redis哨兵 准备工作 搭建过程 模拟主节点宕机,观察哨兵节点的工作流程 哨兵重新选取主节点的流程 1.主观下线 2.客观下线 3.哨兵节点推举出一个leader节点 4.leader选举完毕,leader挑选…

RflySim | 姿态控制器设计实验一

姿态控制器设计实验1 一. 姿态控制设计简介 本文是建立在多旋翼的姿态即控制器中的反馈信号能够被较好地估计的前提下&#xff0c;控制器中的反馈信号是估计值。不过&#xff0c;为了更加简便根据分离原理&#xff0c;我们用真值代替反馈信号。本文的目的是让多旋翼的姿态能够…

Linux入门攻坚——7、磁盘管理——文件系统挂载管理及RAID、LVM

已经安装文件系统的分区需要经过挂载才能使用。 一切文件系统的使用都是从根开始&#xff0c;根是文件系统的起始点。 计算机启动过程&#xff1a;加电自检——bootloader——kernel——rootfs——/sbin/init kernel第一步要加载根系统。 将额外文件系统与根文件系统某现存的…

用swig封装c++代码给python使用

前面我们用swig封装了c的代码给java使用&#xff1a; 如何用SWIG封装c接口给java使用&#xff1f;-CSDN博客 但是由于我们的代码写的太好了&#xff0c;python用户也想用&#xff0c;我们需要将c代码封装一下给python用户使用。 这种需求很常见吧。 现在AI动不动就是用pytho…

Python如何从文件中读取数据

从文件中读取数据 1. 读取整个文件 要读取文件&#xff0c;首先来创建一个文件&#xff1a; 然后打开并读取这个文件&#xff0c;再将其内容显示到屏幕上&#xff1a; file_reader.py with open(pi_digits.txt) as file_object:contents file_object.read()print(contents)…

代码随想录第二十一天(一刷C语言)|回溯算法组合

创作目的&#xff1a;为了方便自己后续复习重点&#xff0c;以及养成写博客的习惯。 一、回溯算法 1、种类 排列、组合、分割、子集、棋盘问题 2、回溯步骤 &#xff08;0&#xff09;回溯抽象 回溯法解决的问题均可以抽象为树形结构&#xff08;N叉树&#xff09; &…

Redis 分布式锁测试

一、前提依赖&#xff08;除去SpringBoot项目基本依赖外&#xff09;&#xff1a; <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId> </dependency><!-- 配置使用redis启动…

【React设计】React企业级设计模式

Image Source : https://bugfender.com React是一个强大的JavaScript库&#xff0c;用于构建用户界面。其基于组件的体系结构和构建可重用组件的能力使其成为许多企业级应用程序的首选。然而&#xff0c;随着应用程序的规模和复杂性的增长&#xff0c;维护和扩展变得更加困难。…

计算机辅助药物设计AIDD-小分子-蛋白质|分子生成|蛋白质配体相互作用预测

文章目录 计算机辅助药物设计AIDD【小分子专题】AIDD概述及药物综合数据库学习机器学习辅助药物设计图神经网络辅助药物设计自然语言处理辅助药物设计药物设计与分子生成 计算机辅助药物设计【蛋白质专题】蛋白质数据结构激酶-Kinase相似性学习基于序列的蛋白质属性预测基于结构…

SSM项目实战-前端-添加分页控件-调正页面布局

1、Index.vue <template><div class"common-layout"><el-container><el-header><el-row><el-col :span"24"><el-button type"primary" plain click"toAdd">新增</el-button></el-…

JavaScript新特性

JavaScript新特性 紧接上文&#xff0c;JS入门手册&#x1f4af; 这篇文章介绍了&#xff0c;JavaScript的基本语法&#xff0c;而随着时代发展&#xff0c;JS早已今非昔比&#xff0c;推荐一个大佬的文章&#xff1a;阮一峰老师 ECMAScript ECMAScript&#xff08;简称“E…

锂电池包膜机通过设备管理系统做好预测性维护的作用

在现代工业生产中&#xff0c;包膜机在锂电产业链中处于电池制造环节&#xff0c;是锂电池生产线上的关键设备之一。然而&#xff0c;随着生产规模的扩大和工作环境的复杂化&#xff0c;锂电池包膜机也面临着常见故障和维护需求。为了更好地管理和维护锂电池包膜机&#xff0c;…

新加坡社区领袖卓顺发的荣誉与大爱精神

2023年11月24日,善济医社义务执行主席卓顺发太平绅士JP, BBM(L), PVPA受邀出席内政部主办的答谢活动2023,主宾为内政部长兼律政部长尚穆根先生(Mr. K Shanmugam)。 2018年起,卓顺发受委为太平绅士后,应内政部邀请,担任纪律咨询委员会委员和巡狱太平绅士及视察团委员。他在颁奖…

Java并发模式和设计策略

引言 小伙伴们&#xff0c;今天小黑要和咱们聊聊Java并发编程的那些事儿。在现代软件开发中&#xff0c;高效地处理多任务是一个不可或缺的能力。特别是对于服务成千上万用户的应用&#xff0c;能够同时处理多个操作不仅是一个加分项&#xff0c;简直是必备技能了&#xff01;…

【openssl】RSA 生成公钥私钥 |通过私钥获取公钥

通过博客&#xff1a;Window系统如何编译openssl 编译出openssl.exe&#xff08;位于apps文件夹下&#xff09;。 现在需要使用它获得公钥私钥、通过私钥获取公钥 目录 说明&#xff01;&#xff01;&#xff01; 一.定位openssl.exe目录 二、进入命令cmd 三、生成私钥 …

IDEA 下载mysql驱动下载在不下来

结合一下 https://www.cnblogs.com/dadian/p/11936056.htmlhttps://www.cnblogs.com/dadian/p/11936056.html并且下载的 在idea改名 加入 加入到库 等待一会就要你输入sql的root和密码了,就OK

冰酒为什么贵?一篇给你讲清楚

冰酒因为昂贵被定义为&#xff1a;颜色和价格都如同黄金的奢侈品。那么&#xff0c;号称液体黄金的冰酒为什么这么贵呢&#xff1f;云仓酒庄给大家讲讲清楚。 云仓酒庄多品牌多代言运营模式&#xff0c;邀请当红明星来出席或代言自身产品&#xff0c;找到与品牌自身形象、调性相…

C语言 操作符详解

C语言学习 目录 文章目录 前言 一、算术操作符 二、移位操作符 2.1 左移操作符 2.2 右移操作符 三、位操作符 3.1 按位与操作符 & 3.2 按位或操作符 | 3.3 按位异或操作符 ^ 四、赋值操作符 五、单目操作符 5.1 逻辑反操作符&#xff01; 5.2 正值、负值-操作符 5.3 取地址…