当前位置: 首页 > news >正文

堆排序详细解读

 

简介

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

堆的概念

  • 堆是一种特殊的树状数据结构,其中每个节点的值大于等于(或小于等于)其子节点的值。是一个平衡二叉树。
  • 最大堆:每个节点的值都大于或等于其子节点的值。
  • 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 开始,并确保该索引下的子节点是最大的。如果子节点的值小于父节点,则交换它们。这个过程会继续,直到满足堆的属性为止。

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

 

 

 

 

 

相关文章:

  • 应急响应-挖矿病毒处理
  • 掌握 Go 语言中的循环结构:从基础到高级
  • ESP32 LVGL Gui-Guider的移植
  • openGauss学习笔记-141 openGauss 数据库运维-例行维护-例行重建索引
  • Python面向对象练习
  • php轻量级性能分析工具 xhprof
  • 场景实践 | 法大大落地业财一体化,优化流程结构
  • SpringBoot之整合JWT
  • 深度学习机器视觉车道线识别与检测 -自动驾驶 计算机竞赛
  • Vue框架学习笔记——列表渲染:v-for
  • canvas绘制小丑
  • 【Vue】使用 Vue CLI 脚手架创建 Vue 项目(使用命令行创建)
  • LeetCode | 104. 二叉树的最大深度
  • Java变量与常量:深入理解基础概念
  • spring mvc理解
  • 实现windows 窗体的自己画,网上摘抄的,学习了
  • 【JavaScript】通过闭包创建具有私有属性的实例对象
  • docker容器内的网络抓包
  • JWT究竟是什么呢?
  • nginx(二):进阶配置介绍--rewrite用法,压缩,https虚拟主机等
  • npx命令介绍
  • Objective-C 中关联引用的概念
  • 从PHP迁移至Golang - 基础篇
  • 第十八天-企业应用架构模式-基本模式
  • 复杂数据处理
  • 基于 Ueditor 的现代化编辑器 Neditor 1.5.4 发布
  • 学习笔记TF060:图像语音结合,看图说话
  • 怎么把视频里的音乐提取出来
  • puppet连载22:define用法
  • scrapy中间件源码分析及常用中间件大全
  • (10)Linux冯诺依曼结构操作系统的再次理解
  • (32位汇编 五)mov/add/sub/and/or/xor/not
  • (react踩过的坑)antd 如何同时获取一个select 的value和 label值
  • (二)WCF的Binding模型
  • (一)eclipse Dynamic web project 工程目录以及文件路径问题
  • (一)RocketMQ初步认识
  • .NET Core 和 .NET Framework 中的 MEF2
  • .NET 设计模式初探
  • .NET 同步与异步 之 原子操作和自旋锁(Interlocked、SpinLock)(九)
  • .NET 中的轻量级线程安全
  • .Net6支持的操作系统版本(.net8已来,你还在用.netframework4.5吗)
  • .net通用权限框架B/S (三)--MODEL层(2)
  • .NET中统一的存储过程调用方法(收藏)
  • @selector(..)警告提示
  • [ C++ ] STL---仿函数与priority_queue
  • [ 数据结构 - C++] AVL树原理及实现
  • []利用定点式具实现:文件读取,完成不同进制之间的
  • [2669]2-2 Time类的定义
  • [android] 练习PopupWindow实现对话框
  • [BT]BUUCTF刷题第4天(3.22)
  • [C++][数据结构][算法]单链式结构的深拷贝
  • [C++]拼图游戏
  • [C++数据结构](31)哈夫曼树,哈夫曼编码与解码
  • [CSS] - 修正IE6不支持position:fixed的bug
  • [CTO札记]盛大文学公司名称对联