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

【算法-堆排序】

堆排序是一种基于堆这种数据结构的比较排序算法,它是一种原地、不稳定的排序算法,时间复杂度为 O(n log n)。堆排序的基本思想是将数组构建成一个二叉堆,并通过反复调整堆顶和未排序部分之间的关系来实现排序。

堆的定义

堆是一种特殊的完全二叉树,分为最大堆和最小堆

  • 最大堆:每个节点的值都大于或等于其子节点的值,堆顶为最大值。
  • 最小堆:每个节点的值都小于或等于其子节点的值,堆顶为最小值。
    在堆排序中,通常使用最大堆来进行升序排序

完全二叉树

堆结构基于完全二叉树(所有层的节点均填满,且最下层的节点靠左排列),通过数组来表示堆,每个节点的索引关系为:

  • 父节点:(i - 1) / 2
  • 左子节点:2 * i + 1
  • 右子节点:2 * i + 2

堆排序的原理

堆排序基于最大堆的特性:

  • 最大堆的堆顶是整个数组的最大值。
  • 通过构建最大堆,将最大值与数组的末尾元素交换,此时堆的大小减少1,排除掉已排好的最大值。
  • 调整剩余的堆,使其继续满足最大堆的性质,重复上述过程,最终得到有序数组。

堆排序的步骤

堆排序分为两个阶段:

  • 构建最大堆:
    从最后一个非叶子节点开始,向上调整每个子树,使其满足最大堆的性质。
  • 排序:
    将堆顶元素与堆的最后一个元素交换,然后对剩余的元素继续调整为最大堆。每次将最大值放在数组的末尾。

Java代码实现

   public class HeapSort {// 主函数:堆排序算法public void heapSort(int[] arr) {int n = arr.length;// 1. 构建最大堆for (int i = n / 2 - 1; i >= 0; i--) {heapify(arr, n, i);}// 2. 一个个将最大值交换到末尾并调整堆for (int i = n - 1; i > 0; i--) {// 将堆顶元素和末尾元素交换swap(arr, 0, i);// 调整堆,去掉已排序的元素heapify(arr, i, 0);}}// 调整堆的函数,确保以root为根的子树满足最大堆性质private void heapify(int[] arr, int n, int root) {int largest = root;int left = 2 * root + 1; // 左子节点int right = 2 * root + 2; // 右子节点// 如果左子节点比root节点大if (left < n && arr[left] > arr[largest]) {largest = left;}// 如果右子节点比当前largest节点大if (right < n && arr[right] > arr[largest]) {largest = right;}// 如果largest不是root,交换root和largestif (largest != root) {swap(arr, root, largest);// 递归地对受影响的子树进行堆调整heapify(arr, n, largest);}}// 辅助函数:交换数组中的两个元素private void swap(int[] arr, int i, int j) {int temp = arr[i];arr[i] = arr[j];arr[j] = temp;}// 打印数组函数public static void printArray(int[] arr) {for (int i : arr) {System.out.print(i + " ");}System.out.println();}// 测试堆排序public static void main(String[] args) {int[] arr = {12, 11, 13, 5, 6, 7};HeapSort heapSort = new HeapSort();System.out.println("原始数组:");printArray(arr);heapSort.heapSort(arr);System.out.println("排序后的数组:");printArray(arr);}
}

输出结果:

原始数组:
12 11 13 5 6 7 
排序后的数组:
5 6 7 11 12 13 

堆排序的时间和空间复杂度

时间复杂度:
构建最大堆:O(n)。
调整堆:每次调整堆的时间复杂度为 O(log n),共进行 n 次调整。因此,堆排序的总体时间复杂度为 O(n log n)。

空间复杂度
堆排序是原地排序算法,不需要额外的存储空间,空间复杂度为 O(1)。

堆排序的优缺点

优点

  • 时间复杂度稳定:堆排序的时间复杂度始终为 O(n log n),无论是最好、最坏还是平均情况。
  • 空间复杂度低:堆排序是原地排序算法,空间复杂度为 O(1),非常节省内存。
  • 不依赖于输入数据的分布:堆排序对输入数据的初始状态不敏感,始终保证 O(n log n) 的时间复杂度。

缺点

  • 不稳定:堆排序可能改变相同元素的相对顺序,因此它不是一个稳定的排序算法。
  • 常数因子较高:堆排序在实际应用中的速度通常比快速排序稍慢,这是因为堆排序中的堆调整操作较复杂。

使用场景

  • 需要稳定时间复杂度的场合:在无法预知输入数据分布,或输入数据最坏情况下其他算法(如快速排序)性能下降时,堆排序是一种保证 O(n log n) 时间复杂度的选择。
  • 内存受限场景:堆排序的空间复杂度为 O(1),因此在内存紧张的场景下非常有用。
  • 优先队列的实现:堆结构常用于实现优先队列等数据结构。

总结

堆排序是一种稳定高效的排序算法,时间复杂度为 O(n log n),空间复杂度为 O(1),具有普遍适用的特点。虽然其不稳定性和相对较高的常数因子可能在某些应用中影响其表现,但在需要稳定时间复杂度和低内存消耗的场合下,堆排序仍然是一个理想的选择。

相关文章:

【算法-堆排序】

堆排序是一种基于堆这种数据结构的比较排序算法&#xff0c;它是一种原地、不稳定的排序算法&#xff0c;时间复杂度为 O(n log n)。堆排序的基本思想是将数组构建成一个二叉堆&#xff0c;并通过反复调整堆顶和未排序部分之间的关系来实现排序。 堆的定义 堆是一种特殊的完全…...

音视频入门基础:AAC专题(4)——ADTS格式的AAC裸流实例分析

音视频入门基础&#xff1a;AAC专题系列文章&#xff1a; 音视频入门基础&#xff1a;AAC专题&#xff08;1&#xff09;——AAC官方文档下载 音视频入门基础&#xff1a;AAC专题&#xff08;2&#xff09;——使用FFmpeg命令生成AAC裸流文件 音视频入门基础&#xff1a;AAC…...

【第33章】Spring Cloud之SkyWalking服务链路追踪

文章目录 前言一、介绍1. 架构图2. SkyWalking APM 二、服务端和控制台1. 下载2. 解压3. 初始化数据库4. 增加驱动5. 修改后端配置6. 启动7. 访问控制台8. 数据库表 三、客户端1. 下载2. 设置java代理3. idea配置3.1 环境变量3.2 JVM参数3.3 启动日志 4. 启用网关插件 四、链路…...

如何选择OS--Linux不同Distribution的选用

写在前言&#xff1a; 刚写了Windows PC的不同editions的选用&#xff0c;趁热&#xff0c;把Linux不同的Distribution选用也介绍下&#xff0c;希望童鞋们可以了解-->理解-->深入了解-->深入理解--...以致于能掌握特定版本的Linux的使用甚者精通。……^.^…… so&a…...

cesium效果不酷炫怎么办--增加渲染器

DrawCommand 可以发挥 WebGL 全部潜力吗&#xff1f; 回答&#xff1a; Cesium 的 DrawCommand 是一个用于表示 WebGL 渲染管线中单个绘制调用的低级抽象。它封装了执行 WebGL 绘制所需的所有信息&#xff0c;包括着色器程序、顶点数组、渲染状态、统一变量&#xff08;unifo…...

计算机网络:概述 --- 体系结构

目录 一. 体系结构总览 1.1 OSI七层协议体系结构 1.2 TCP/IP四层(或五层)模型结构 二. 数据传输过程 2.1 同网段传输 2.2 跨网段传输 三. 体系结构相关概念 3.1 实体 3.2 协议 3.3 服务 这里我们专门来讲一下计算机网络中的体系结构。其实我们之前…...

DEPLOT: One-shot visual language reasoning by plot-to-table translation论文阅读

文章链接&#xff1a;https://arxiv.org/abs/2308.01979http://arxiv.org/abs/2212.10505https://arxiv.org/abs/2308.01979 源码链接&#xff1a;https://github.com/cse-ai-lab/RealCQA 启发&#xff1a;two-stage方法可能是未来主要研究方向&#xff0c;能够增强模型可解释…...

从 HDFS 迁移到 MinIO 企业对象存储

云原生、面向 Kubernetes 、基于微服务的架构推动了对 MinIO 等网络存储的需求。在云原生环境中&#xff0c;对象存储的优势很多 - 它允许独立于存储硬件对计算硬件进行弹性扩展。它使应用程序无状态&#xff0c;因为状态是通过网络存储的&#xff0c;并且通过降低操作复杂性&a…...

Rust 常见问题汇总

问题1&#xff1a; cargo build 一直提示Blocking waiting for file lock on package cache。 在 cargo.toml 文件中添加了依赖之后&#xff0c;运行 cargo build 命令时&#xff0c;如果卡在 blocking waiting for file lock on package cache lock 这里&#xff0c; 后来发…...

java泛型类与泛型方法

Java泛型类和泛型方法是Java泛型编程中的重要组成部分。它们允许开发者编写类型安全且高度复用的代码。下面详细介绍泛型类和泛型方法的概念、用法和示例。 泛型类 泛型类是在类定义中使用类型参数的类&#xff0c;可以指定具体的类型实例化该类。这样可以确保类型安全&#…...

Android String资源文件中,空格、换行以及特殊字符如何表示

空格&#xff1a; 例&#xff1a;<string name"test">test test</string> 换行&#xff1a;\n 例&#xff1a;<string name"test">test \n test</string> tab&#xff1a;\t …...

CUDA及GPU学习资源汇总

CUDA C Programming Guide 的中文翻译版GPU中的SM和warp的关系推荐几个不错的CUDA入门教程CUDA编程入门极简教程...

uniapp vue3 梯形选项卡组件

实现的效果图&#xff1a; 切换选项卡显示不同的内容&#xff0c;把这个选项卡做成了一个组件&#xff0c;需要的自取。 // 组件名为 trapezoidalTab <template> <view class"pd24"><view class"nav"><!-- 左侧 --><view cla…...

如何在微信小程序中实现WebSocket连接

微信小程序作为一种全新的应用形态&#xff0c;凭借其便捷性、易用性受到了广大用户的喜爱。在实际开发过程中&#xff0c;实时通信功能是很多小程序必备的需求。WebSocket作为一种在单个TCP连接上进行全双工通信的协议&#xff0c;能够实现客户端与服务器之间的实时通信。本文…...

二级等保测评中安全物理环境的重要性及高危项分析

当今数字化时代&#xff0c;信息安全至关重要。网络安全等级保护测评是确保信息系统安全稳定运行的重要手段之一&#xff0c;其中二级等保测评对于许多企业和组织来说是必须要达到的安全标准。 而安全物理环境作为等保测评的重要组成部分&#xff0c;其重要性不容忽视。 安全物…...

C++11——lambda

lambda lambda的介绍lambda的使用lambda的细节->捕捉列表 lambda的介绍 lambda是匿名函数&#xff0c;再适合的场景去使用可以提高代码的可读性。 场景&#xff1a; 假设有一个Goods类需要进行按照价格、数量排序 class Goods {string name;size_t _price;//价格int num;/…...

Dubbo3序列化安全问题

序列化安全 在 Dubbo 3.0 中&#xff0c;序列化协议的安全性得到了加强。 1. 序列化安全性升级 Triple 协议: 推荐使用 Triple 协议 的非 Wrapper 模式&#xff0c;该模式在安全性上更为严格。需要开发人员编写 IDL&#xff08;接口描述语言&#xff09;文件&#xff0c;这虽…...

秒懂Linux之共享内存

目录 共享内存概念 模拟实现共享内存 创建key阶段 ​编辑创建共享内存阶段 删除共享内存阶段 查看共享内存属性阶段 挂接共享内存到进程阶段 取消共享内存与进程挂接阶段 进程通信阶段 添加管道改进版 共享内存函数 shmget函数 shmat函数 shmdt函数 shmctl函数 共享内存概念 共…...

【计算机网络】网络层协议解析

网络层的两种服务IPv4分类编址划分子网无分类地址 IPv4地址应用IP数据报的发送和转发过程主机发送IP数据报路由器转发IP数据报 IPv4数据报首部格式ICMP网际控制报文协议虚拟专用网VPN与网络地址转换NAT 网络层主要任务是实现网络互连&#xff0c;进而实现数据包在各网络之间的传…...

sqlist void reverse(SqList A)

#include <stdlib.h> #include <stdio.h> #include <iostream> using namespace std; #define INIT_SIZE 5 #define INCREMENT 10 # define OK 1 # define ERROR 0/* 定义ElemType为int类型 */ typedef int ElemType; void input(ElemType &s); void out…...

ai赋能开发:在快马平台用自然语言描述,自动生成java swing计算器代码

最近想用Java Swing开发一个图形化计算器&#xff0c;但作为初学者对Swing库不太熟悉。好在发现了InsCode(快马)平台&#xff0c;它内置的AI辅助开发功能帮我轻松解决了这个问题。整个过程就像有个编程助手在实时指导&#xff0c;特别适合我这种想快速实现功能但又不想深陷语法…...

手机也能跑AI?实测3B以下小模型在安卓/iOS端的部署教程(附性能对比)

手机端AI模型实战&#xff1a;3B以下小模型在安卓/iOS的部署与优化指南 当ChatGPT需要数据中心级算力支撑时&#xff0c;你可能没想到自己的手机也能运行类似技术。本文将带你探索移动端AI部署的完整方案——从Termux环境配置到CoreML模型转换&#xff0c;实测Redmi Note 12 Tu…...

Tomcat安全防护指南:如何用TomcatScanPro检测CVE-2017-12615和AJP文件包含漏洞

Tomcat安全防护实战&#xff1a;从漏洞检测到加固的全链路解决方案 在企业级Java应用部署中&#xff0c;Tomcat作为最流行的Web服务器之一&#xff0c;其安全性直接关系到业务系统的稳定运行。本文将深入剖析两个高危漏洞&#xff08;CVE-2017-12615和AJP文件包含&#xff09;的…...

Python包管理工具之uv的使用详细指南

uv 是一个新兴的 Python 包管理工具&#xff0c;它旨在提供比 pip 和 poetry 更快、更现代的依赖管理体验。uv 由 Charles Murphy 开发&#xff0c;基于 Rust 构建&#xff0c;具有极高的性能和兼容性&#xff0c;支持标准的 requirements.txt 文件以及 pyproject.toml 中的依赖…...

救命!2026爆款PPT一键制作工具实测,新手也能5分钟出片,告别熬夜手搓无标题

作为常年和PPT打交道的AI博主&#xff0c;每天都能收到粉丝私信轰炸&#xff1a;“做PPT有没有捷径&#xff1f;”“AI能不能帮我快速出稿&#xff1f;”“新手零基础&#xff0c;半天排不出一页像样的版面”……懂的都懂&#xff01;谁没为了一份PPT熬到凌晨&#xff1f;找模板…...

效率倍增:用快马生成万文通核心文本处理模块,告别重复编码

效率倍增&#xff1a;用快马生成万文通核心文本处理模块&#xff0c;告别重复编码 最近在开发一个多语言文本处理工具"万文通"&#xff0c;需要频繁实现翻译、摘要和关键词提取功能。每次从零开始写这些基础模块太耗时&#xff0c;于是我尝试用InsCode(快马)平台快速…...

别再死记硬背了!用一张图+代码示例,彻底搞懂蓝牙BLE配对的6种SMP流程

蓝牙BLE安全配对实战图解&#xff1a;6种SMP流程与核心算法拆解 每次看到蓝牙协议栈里那些晦涩的安全管理协议&#xff08;SMP&#xff09;文档就头疼&#xff1f;别担心&#xff0c;今天我们用工程师的思维来重新解构这个"安全黑匣子"。扔掉那些让人昏昏欲睡的文字…...

Codesys的CNC模块到底怎么用?手把手教你用WPF上位机联动,实现G代码解析与虚拟轴运动

Codesys CNC模块实战&#xff1a;WPF上位机与虚拟轴联动的G代码解析系统 1. 工业控制新范式&#xff1a;软硬件协同的虚拟调试方案 在智能制造和工业4.0背景下&#xff0c;控制系统开发正经历从传统硬件依赖到软件定义的转型。作为工业自动化领域的瑞士军刀&#xff0c;Codesys…...

树莓派3B+安装OpenMediaVault(OMV)后WiFi配置失效的快速修复指南

1. 问题现象与原因分析 最近在树莓派3B上折腾OpenMediaVault&#xff08;OMV&#xff09;时遇到了一个典型问题&#xff1a;安装完OMV后&#xff0c;原本配置好的WiFi突然无法连接了。这个现象特别常见于使用Raspberry Pi OS Lite系统的用户&#xff0c;我自己用的就是Bookworm…...

从数学原理到代码实现:手把手推导Transformer时间复杂度公式(附PyTorch示例)

从数学原理到代码实现&#xff1a;手把手推导Transformer时间复杂度公式&#xff08;附PyTorch示例&#xff09; 在自然语言处理领域&#xff0c;Transformer架构已经成为事实上的标准模型。但当我们处理长文本序列时&#xff0c;经常会遇到计算资源急剧增加的问题。这背后的核…...