Java算法之堆排序(Heap Sort)

堆排序简介

堆排序是一种基于比较的排序算法,它使用二叉堆数据结构来实现。二叉堆是一种特殊的完全二叉树,其中每个父节点的键值都大于(或等于)其子节点的键值(大顶堆),或者小于(或等于)其子节点的键值(小顶堆)。堆排序通过维护堆的性质来高效地组织数据,从而实现排序。

算法原理

堆排序的工作原理包括两个主要部分:

  1. 构建初始堆:将无序数组转换成堆结构。
  2. 排序:重复从堆顶移除最大元素(大顶堆)或最小元素(小顶堆),然后重新调整堆结构,直到所有元素都被移除。

代码实现

以下是使用Java实现堆排序的示例代码:

public class HeapSort {// 交换数组中的两个元素private static void swap(int[] arr, int i, int j) {int temp = arr[i];arr[i] = arr[j];arr[j] = temp;}// 向下调整堆,确保堆的性质private static void heapify(int[] arr, int n, int i) {int largest = i; // 初始假设根是最大的int left = 2 * i + 1; // 左子节点int right = 2 * i + 2; // 右子节点// 如果左子节点存在且大于根节点if (left < n && arr[left] > arr[largest]) {largest = left;}// 如果右子节点存在且大于最大的节点if (right < n && arr[right] > arr[largest]) {largest = right;}// 如果最大的节点不是根节点,交换它们,并继续向下调整if (largest != i) {swap(arr, i, largest);heapify(arr, n, largest); // 递归地调整堆}}// 堆排序函数public static void heapSort(int[] arr) {int n = arr.length;// 构建初始堆for (int i = n / 2 - 1; i >= 0; i--) {heapify(arr, n, i);}// 从堆中移除最大元素,并重新调整堆for (int i = n - 1; i > 0; i--) {swap(arr, 0, i); // 将当前最大元素移到数组末尾heapify(arr, i, 0); // 重新调整剩余元素的堆结构}}public static void main(String[] args) {int[] arr = {12, 11, 13, 5, 6, 7};heapSort(arr);System.out.println("排序后的数组: ");for (int value : arr) {System.out.print(value + " ");}}
}

优缺点分析

优点

  • 时间复杂度:堆排序的时间复杂度为O(n log n),在大多数情况下表现良好。
  • 空间复杂度:堆排序是原地排序算法,空间复杂度为O(1)。
  • 可并行化:堆排序的构建和调整过程可以并行执行,适合在多核处理器上实现。

缺点

  • 不稳定性:堆排序是不稳定的排序算法,相等的元素在排序后可能会改变顺序。
  • 对小数据集效率低:对于小规模数据集,堆排序可能不如其他简单算法(如插入排序)高效。

使用场景

  • 大数据集:堆排序适合对大数据集进行排序,尤其是在内存受限的情况下。
  • 需要原地排序:当需要在不增加额外内存使用的情况下进行排序时,堆排序是一个好选择。
  • 优先队列实现:堆排序常用于实现优先队列,用于处理需要频繁插入和删除最大(或最小)元素的场景。

结语

堆排序是一种高效的排序算法,尤其适合处理大数据集和实现优先队列。虽然它不是稳定的排序算法,但其原地排序的特性和对并行化的支持使其在许多应用场景下非常有价值

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

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

相关文章

docker在宿主机上最多可以创建多少个容器?

docker在宿主机上最多可以创建多少个容器&#xff1f; A. 1000 B. 和宿主机的cpu/memory 资源有关系 C. 不一定 选择C Docker 容器的数量受到宿主机的资源限制&#xff0c;包括CPU、内存和存储空间等。具体的容器数量取决于宿主机的硬件配置和资源使用情况。没有固定的数量限…

Springboot里集成Mybatis-plus、ClickHouse

&#x1f339;作者主页&#xff1a;青花锁 &#x1f339;简介&#xff1a;Java领域优质创作者&#x1f3c6;、Java微服务架构公号作者&#x1f604; &#x1f339;简历模板、学习资料、面试题库、技术互助 &#x1f339;文末获取联系方式 &#x1f4dd; Springboot里集成Mybati…

基于Java+SpringBoot+Vue的汽车销售网站

基于JavaSpringBootVue的汽车销售网站 前言 ✌全网粉丝20W,csdn特邀作者、博客专家、CSDN[新星计划]导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345; 某信 gzh 搜索【智能编程小助手】获取项…

【大模型】llama系列模型基础

前言&#xff1a;llama基于transformer架构&#xff0c;与GPT相似&#xff0c;只用了transformer的解码器部分。本文主要是关于llama&#xff0c;llama2和llama3的结构解读。 目录 1. llama1.1 整体结构1.2 RoPE1.3 SwiGLU 激活函数 2. llama22.2 GQA架构2.3 RLHF 3. llama3参考…

javascript用while语句计算1-100的和

while语句计算1-100的和的思路是 定义一个变量a1,变量b0 while(a<100) { bba或者ba a } 最后是输出b <html><head><meta charset"UTF-8"><title></title></head><body><script>let i1let a0while(i<1…

Springboot中使用Elasticsearch(部署+使用+讲解 最完整)

目录 引言 一、docker中安装Elasticsearch 1、创建es专有的网络 2、开放端口 3、在es-net网络上安装es和kibana 4、可能出现的问题 5、测试 6、安装IK分词器 7、测试IK分词器 二、结合业务实战 1、准备依赖 2、配置yml 3、读取yml配置 4、准备es配置类 5、编写测…

Leetcode面试经典150题-136.只出现一次的数字

解法都在代码里&#xff0c;不懂就留言或者私信 这个题不知道为啥会考&#xff0c;过于简单了&#xff0c;我解题写注释用了两分钟不到&#xff0c;5行代码。。。 class Solution {public int singleNumber(int[] nums) {/**这个题目确实时间的题&#xff0c;根据位运算法则我…

依赖倒置原则详细介绍

一.概念 依赖倒置原则(Dependency Inversion Principle, DIP)是SOLID五大设计原则之一,它是面向对象设计中非常重要的一个原则。它主要包含以下两个方面: 高层模块不应该依赖于低层模块,两者都应该依赖于抽象。 这意味着高层模块(上层)不应该直接依赖于低层模块(下层)的实现…

创建表与删除表

创建表 使用DDL语句创建表 CREATE TABLE 表名(列名 类型,列名 类型......); 示例&#xff1a; 创建一个employees表包含雇员ID&#xff0c;雇员名字&#xff0c;雇员薪水。 create table employees(employee_id int,employee_name varchar(10),salary float(8,2)); 查看已…

斗破C++编程入门系列之十九:C++程序设计必知:多文件结构和编译预处理命令(九星斗者)

斗破C目录&#xff1a; 斗破C编程入门系列之前言&#xff08;斗之气三段&#xff09; 斗破C编程入门系列之二&#xff1a;Qt的使用介绍&#xff08;斗之气三段&#xff09; 斗破C编程入门系列之三&#xff1a;数据结构&#xff08;斗之气三段&#xff09; 斗破C编程入门系列之…

ctfshow之web55~web57(无字母的rce)

目录 web55 思路一&#xff1a; 思路二&#xff1a; web56 web57 本系列主要针对无字母rce或无字母无数字rce 声明&#xff1a;本章内容是引荐几位师傅的博客&#xff0c;然后根据自己的理解编写而成。 web55 if(isset($_GET[c])){$c$_GET[c];if(!preg_match("/\…

gin 通过 OpenTelemetry 实现链路追踪

OpenTelemetry 可用于跟踪 Gin 应用程序的性能问题和错误。 OpenTelemetry 是 Cloud Native Computing Foundation (CNCF) 下的一个开源项目,旨在标准化遥测数据的生成和收集。遥测数据包括日志、指标和跟踪。 Gin 是一个用 Go (Golang) 编写的 HTTP Web 框架。它具有类似 Mar…

乐凡三防:工业界的硬核产品——重新定义三防平板的极限

在工业4.0的浪潮中&#xff0c;科技与制造业的深度融合催生了一系列高性能、高耐用的智能产品。乐凡三防平板&#xff0c;作为工业界的新宠&#xff0c;正以其卓越的防护性能和强大的功能&#xff0c;重新定义了三防平板的极限&#xff0c;成为硬核科技的代表。 硬核防护&#…

GD32F4xx---RTC初始化设置及闹钟方式实现秒中断讲解

GD32F4xx—RTC初始化设置及闹钟方式实现秒中断讲解 1、下载链接:源码工程 一、概述 GD32F4x的RTC例程网上资源较少,详细阅读用户手册后做出如下配置。RTC模块提供了一个包含日期(年/月/日)和时间(时/分/秒/亚秒)的日历功能。除亚秒用二进制码显示外,时间和日期都以BC…

大连网站建设手机网页页面设计

在现代社会&#xff0c;随着智能手机的普及&#xff0c;越来越多的用户选择通过手机访问网站&#xff0c;这使得移动端网页设计的重要性日益凸显。大连作为一个经济和文化中心&#xff0c;网站建设行业也在不断发展。针对大连的网站建设&#xff0c;手机网页页面设计需要特别注…

【Java设计模式】事件溯源模式

文章目录 【Java设计模式】事件溯源模式一、概述二、别名三、事件溯源设计模式的意图四、通过实际示例详细解释事件溯源模式五、Java中事件溯源模式的编程示例六、何时在Java中使用事件溯源模式七、事件溯源模式在Java中的实际应用八、事件溯源模式的好处和权衡九、源码下载 【…

如何清理Linux旧内核并设置默认内核版本

文章目录 1. 引言2. 检查和清理旧内核2.1 检查 /boot 目录中的残留文件2.2 手动删除与旧内核相关的文件2.3 更新 GRUB 配置2.4 清理旧内核包&#xff08;可选&#xff09; 3. 安装并保留特定内核版本3.1 安装内核版本 5.15.0-1193.2 删除其他不需要的内核版本 4. 设置默认内核版…

内存管理篇-16二级页表工作原理

1.修正上节课的转换图 上节课的页表的一级页表其实并不完全正确&#xff0c;一般虚拟页帧和物理页帧号不会都占用实际字段&#xff0c;这样毕竟很浪费内存。 2.再分析一下页表的开销情况&#xff1a; 一级页表&#xff1a;以4KB物理页为映射单位&#xff0c;每个进程4MB的虚…

动态读取nacos中修改的项目配置文件

本项目用的还是springboot项目&#xff0c;咱们直接上代码 一&#xff1a;首先看下nacos中需要动态获取的属性 二&#xff1a;把需要动态读取的配置类中的属性整理一个实体类 mport lombok.Data; import org.springframework.boot.context.properties.ConfigurationPropert…

Python酷库之旅-第三方库Pandas(114)

目录 一、用法精讲 501、pandas.DataFrame.mode方法 501-1、语法 501-2、参数 501-3、功能 501-4、返回值 501-5、说明 501-6、用法 501-6-1、数据准备 501-6-2、代码示例 501-6-3、结果输出 502、pandas.DataFrame.pct_change方法 502-1、语法 502-2、参数 502…