堆排序详细解读

news2024/11/17 8:31:52

 

简介

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

堆的概念

  • 堆是一种特殊的树状数据结构,其中每个节点的值大于等于(或小于等于)其子节点的值。是一个平衡二叉树。
  • 最大堆:每个节点的值都大于或等于其子节点的值。
  • 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.coloradmin.cn/o/1283821.html

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

相关文章

YOLOv3 快速上手:Windows 10上的训练环境搭建

文章目录 前言一、前期准备二、基础环境准备1. 创建虚拟环境2. 打开Terminal3. 下载YOLOv3运行环境 三、PyCharm关联3.1 运行PyCharm3.2 关联Anaconda虚拟环境 四、运行环境检查1. 检查requirements.txt文件2. 安装依赖 五、运行代码5.1 运行检测代码5.2 运行训练代码 六、常见…

Python中的类(Class)和对象(Object)

目录 一、引言 二、类&#xff08;Class&#xff09; 1、类的定义 2、类的实例化 三、对象&#xff08;Object&#xff09; 1、对象的属性 2、对象的方法 四、类和对象的继承和多态性 1、继承 2、多态性 五、类与对象的封装性 1、封装的概念 2、Python中的封装实现…

cmd查看进程信息 终止进程

cmd查看进程信息 终止进程 1、cmd查看进程信息2、终止进程 1、cmd查看进程信息 tasklist命令 描述: 该工具显示在本地或远程机器上当前运行的进程列表。 tasklist /?查看本机所有进程列表 tasklist /V根据进程名 查看jmeter进程 tasklist /V |findstr /i jmeter2、终止进程…

操作系统·设备管理

I/O系统是计算机系统的重要组成部分&#xff0c;是OS中最复杂且与硬件密切相关的部分 I/O系统的基本任务是完成用户提出的I/O请求&#xff0c;提高I/O速率以及改善I/O设备的利用率&#xff0c;方便高层进程对IO设备的使用 I/O系统包括用于实现信息输入、输出和存储功能的设备和…

C++ 系列 第四篇 C++ 数据类型上篇—基本类型

系列文章 C 系列 前篇 为什么学习C 及学习计划-CSDN博客 C 系列 第一篇 开发环境搭建&#xff08;WSL 方向&#xff09;-CSDN博客 C 系列 第二篇 你真的了解C吗&#xff1f;本篇带你走进C的世界-CSDN博客 C 系列 第三篇 C程序的基本结构-CSDN博客 前言 面向对象编程(OOP)的…

[多线程]阻塞队列和生产者消费者模型

目录 1.阻塞队列 1.1引言 1.2Java标准库中的阻塞队列 1.3自主通过Java代码实现一个阻塞队列(泛型实现) 2.生产者消费者模型 1.阻塞队列 1.1引言 阻塞队列是多线程部分一个重要的概念,它相比于一般队列,有两个特点: 1.线程是安全的 2.带有阻塞功能 1) 队列为空,出队列就会阻…

Android wifi连接和获取IP分析

wifi 连接&获取IP 流程图 代码流程分析 一、关联阶段 1. WifiSettings.submit – > WifiManager WifiSettings 干的事情比较简单&#xff0c;当在dialog完成ssid 以及密码填充后&#xff0c;直接call WifiManager save 即可WifiManager 收到Save 之后&#xff0c;就开…

C++实现顺序栈的基本操作(扩展)

#include <stdio.h> typedef char ElemType; #define StackSize 100 /*顺序栈的初始分配空间*/ typedef struct { ElemType data[StackSize]; /*保存栈中元素*/int top; /*栈顶指针*/ } SqStack; void InitStack(SqStack &st) {st.top-1; } …

质量小议35 -- SQL注入

已经记不得上次用到SQL注入是什么时候了&#xff0c;一些概念和操作已经模糊。 最近与人聊起SQL注入&#xff0c;重新翻阅&#xff0c;暂记于此。 重点&#xff1a;敏感信息、权限过大、未脱敏的输入/输出、协议、框架、数据包、明文、安全意识 SQL - Structured Query La…

实战技巧:为Android应用设置独立的多语言

原文链接 实战技巧&#xff1a;为Android应用设置独立的多语言 通常情况下多语言的设置都在系统设置中&#xff0c;应用需要做的就是提供本应用所使用的字串的多语言翻译&#xff0c;使用时使用R.string.app_name类似的引用&#xff0c;然后系统会根据用户在系统设置中的选项来…

Kubernetes存储搭建NFS挂载失败处理

搞NFS存储时候发现如下问题&#xff1a; Events:Type Reason Age From Message---- ------ ---- ---- -------Normal Scheduled 5m1s default-scheduler Successful…

【hacker送书第8期】Java从入门到精通(第7版)

第8期图书推荐 内容简介编辑推荐作者简介图书目录参与方式 内容简介 《Java从入门到精通&#xff08;第7版&#xff09;》从初学者角度出发&#xff0c;通过通俗易懂的语言、丰富多彩的实例&#xff0c;详细讲解了使用Java语言进行程序开发需要掌握的知识。全书分为4篇共24章&a…

玩转大数据5:构建可扩展的大数据架构

1. 引言 随着数字化时代的到来&#xff0c;大数据已经成为企业、组织和个人关注的焦点。大数据架构作为大数据应用的核心组成部分&#xff0c;对于企业的数字化转型和信息化建设至关重要。我们将探讨大数据架构的基本要素和原则&#xff0c;以及Java在大数据架构中的角色&…

智能优化算法(二):禁忌搜索算法

文章目录 禁忌搜索算法1.禁忌搜索算法预备知识1.1 预备知识1---解空间1.2.预备知识2---邻域 2.禁忌搜索算法实现过程2.1.禁忌搜索算法思想2.2.禁忌搜索构成要素2.2.1.搜索结果表达2.2.2.邻域移动策略2.2.3.禁忌表引入2.2.4.禁忌搜索选择策略2.2.5.禁忌搜索渴望水平2.2.6.禁忌搜…

UEC++ 探索虚幻5笔记 day11

虚幻5.2.1探索 项目目录探索 C工程一定不能是中文路径&#xff0c;中文项目名&#xff0c;最好全部不要用中文&#xff0c;蓝图项目可以是中文浅浅创建一个空项目&#xff0c;讲解一下之前UE4没有讲解的项目目录文件的分布组成 .vs&#xff1a;文件夹一般是项目编译缓存文件夹…

Deployment脚本部署Tomcat集群:外部访问、负载均衡、文件共享及集群配置调整

文章目录 前置知识一、Deployment脚本部署Tomcat集群二、外部访问Tomcat集群三、利用Rinted对外提供Service负载均衡支持1、创建服务2、端口转发工具Rinetd3、定义jsp文件查看转发到哪个节点 四、部署配置挂载点五、基于NFS实现集群文件共享1、master2、node3、验证 六、集群配…

ESP32-Web-Server编程-通过 Web 下载文本

ESP32-Web-Server编程-通过 Web 下载文本 概述 当你希望通过网页导出设备的数据时&#xff0c;可以在 ESP32 上部署一个简单的文件 Web 服务器。 需求及功能解析 本节演示如何在 ESP32 上部署一个最简单的 Web 服务器&#xff0c;来接收浏览器或者 wget 指令请求文件数据。…

Course2-Week2-神经网络的训练方法

Course2-Week2-神经网络的训练方法 文章目录 Course2-Week2-神经网络的训练方法1. 神经网络的编译和训练1.1 TensorFlow实现1.2 损失函数和代价函数的数学公式 2. 其他的激活函数2.1 Sigmoid激活函数的替代方案2.2 如何选择激活函数2.3 为什么需要激活函数 3. 多分类问题和Soft…

时间序列数据压缩算法简述

本文简单介绍了时间序列压缩任务的来源&#xff0c;压缩算法的分类&#xff0c;并对常见压缩算法的优缺点进行了简介&#xff0c;爱码士们快来一探究竟呀&#xff01; 引言 时间序列数据是在许多应用程序和领域中生成的一种基本数据类型&#xff0c;例如金融、医疗保健、交通和…

智能优化算法应用:基于阿基米德优化算法无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于阿基米德优化算法无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于阿基米德优化算法无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.阿基米德优化算法4.实验参数设定5.算…