【算法-堆排序】
堆排序是一种基于堆这种数据结构的比较排序算法,它是一种原地、不稳定的排序算法,时间复杂度为 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),具有普遍适用的特点。虽然其不稳定性和相对较高的常数因子可能在某些应用中影响其表现,但在需要稳定时间复杂度和低内存消耗的场合下,堆排序仍然是一个理想的选择。
相关文章:
【算法-堆排序】
堆排序是一种基于堆这种数据结构的比较排序算法,它是一种原地、不稳定的排序算法,时间复杂度为 O(n log n)。堆排序的基本思想是将数组构建成一个二叉堆,并通过反复调整堆顶和未排序部分之间的关系来实现排序。 堆的定义 堆是一种特殊的完全…...

音视频入门基础:AAC专题(4)——ADTS格式的AAC裸流实例分析
音视频入门基础:AAC专题系列文章: 音视频入门基础:AAC专题(1)——AAC官方文档下载 音视频入门基础:AAC专题(2)——使用FFmpeg命令生成AAC裸流文件 音视频入门基础: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的选用
写在前言: 刚写了Windows PC的不同editions的选用,趁热,把Linux不同的Distribution选用也介绍下,希望童鞋们可以了解-->理解-->深入了解-->深入理解--...以致于能掌握特定版本的Linux的使用甚者精通。……^.^…… so&a…...
cesium效果不酷炫怎么办--增加渲染器
DrawCommand 可以发挥 WebGL 全部潜力吗? 回答: Cesium 的 DrawCommand 是一个用于表示 WebGL 渲染管线中单个绘制调用的低级抽象。它封装了执行 WebGL 绘制所需的所有信息,包括着色器程序、顶点数组、渲染状态、统一变量(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论文阅读
文章链接:https://arxiv.org/abs/2308.01979http://arxiv.org/abs/2212.10505https://arxiv.org/abs/2308.01979 源码链接:https://github.com/cse-ai-lab/RealCQA 启发:two-stage方法可能是未来主要研究方向,能够增强模型可解释…...

从 HDFS 迁移到 MinIO 企业对象存储
云原生、面向 Kubernetes 、基于微服务的架构推动了对 MinIO 等网络存储的需求。在云原生环境中,对象存储的优势很多 - 它允许独立于存储硬件对计算硬件进行弹性扩展。它使应用程序无状态,因为状态是通过网络存储的,并且通过降低操作复杂性&a…...
Rust 常见问题汇总
问题1: cargo build 一直提示Blocking waiting for file lock on package cache。 在 cargo.toml 文件中添加了依赖之后,运行 cargo build 命令时,如果卡在 blocking waiting for file lock on package cache lock 这里, 后来发…...
java泛型类与泛型方法
Java泛型类和泛型方法是Java泛型编程中的重要组成部分。它们允许开发者编写类型安全且高度复用的代码。下面详细介绍泛型类和泛型方法的概念、用法和示例。 泛型类 泛型类是在类定义中使用类型参数的类,可以指定具体的类型实例化该类。这样可以确保类型安全&#…...
Android String资源文件中,空格、换行以及特殊字符如何表示
空格: 例:<string name"test">test test</string> 换行:\n 例:<string name"test">test \n test</string> tab:\t …...
CUDA及GPU学习资源汇总
CUDA C Programming Guide 的中文翻译版GPU中的SM和warp的关系推荐几个不错的CUDA入门教程CUDA编程入门极简教程...

uniapp vue3 梯形选项卡组件
实现的效果图: 切换选项卡显示不同的内容,把这个选项卡做成了一个组件,需要的自取。 // 组件名为 trapezoidalTab <template> <view class"pd24"><view class"nav"><!-- 左侧 --><view cla…...
如何在微信小程序中实现WebSocket连接
微信小程序作为一种全新的应用形态,凭借其便捷性、易用性受到了广大用户的喜爱。在实际开发过程中,实时通信功能是很多小程序必备的需求。WebSocket作为一种在单个TCP连接上进行全双工通信的协议,能够实现客户端与服务器之间的实时通信。本文…...
二级等保测评中安全物理环境的重要性及高危项分析
当今数字化时代,信息安全至关重要。网络安全等级保护测评是确保信息系统安全稳定运行的重要手段之一,其中二级等保测评对于许多企业和组织来说是必须要达到的安全标准。 而安全物理环境作为等保测评的重要组成部分,其重要性不容忽视。 安全物…...

C++11——lambda
lambda lambda的介绍lambda的使用lambda的细节->捕捉列表 lambda的介绍 lambda是匿名函数,再适合的场景去使用可以提高代码的可读性。 场景: 假设有一个Goods类需要进行按照价格、数量排序 class Goods {string name;size_t _price;//价格int num;/…...
Dubbo3序列化安全问题
序列化安全 在 Dubbo 3.0 中,序列化协议的安全性得到了加强。 1. 序列化安全性升级 Triple 协议: 推荐使用 Triple 协议 的非 Wrapper 模式,该模式在安全性上更为严格。需要开发人员编写 IDL(接口描述语言)文件,这虽…...

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

【计算机网络】网络层协议解析
网络层的两种服务IPv4分类编址划分子网无分类地址 IPv4地址应用IP数据报的发送和转发过程主机发送IP数据报路由器转发IP数据报 IPv4数据报首部格式ICMP网际控制报文协议虚拟专用网VPN与网络地址转换NAT 网络层主要任务是实现网络互连,进而实现数据包在各网络之间的传…...
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…...

网络六边形受到攻击
大家读完觉得有帮助记得关注和点赞!!! 抽象 现代智能交通系统 (ITS) 的一个关键要求是能够以安全、可靠和匿名的方式从互联车辆和移动设备收集地理参考数据。Nexagon 协议建立在 IETF 定位器/ID 分离协议 (…...
【网络】每天掌握一个Linux命令 - iftop
在Linux系统中,iftop是网络管理的得力助手,能实时监控网络流量、连接情况等,帮助排查网络异常。接下来从多方面详细介绍它。 目录 【网络】每天掌握一个Linux命令 - iftop工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景…...

XCTF-web-easyupload
试了试php,php7,pht,phtml等,都没有用 尝试.user.ini 抓包修改将.user.ini修改为jpg图片 在上传一个123.jpg 用蚁剑连接,得到flag...
基于大模型的 UI 自动化系统
基于大模型的 UI 自动化系统 下面是一个完整的 Python 系统,利用大模型实现智能 UI 自动化,结合计算机视觉和自然语言处理技术,实现"看屏操作"的能力。 系统架构设计 #mermaid-svg-2gn2GRvh5WCP2ktF {font-family:"trebuchet ms",verdana,arial,sans-…...
论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(二)
HoST框架核心实现方法详解 - 论文深度解读(第二部分) 《Learning Humanoid Standing-up Control across Diverse Postures》 系列文章: 论文深度解读 + 算法与代码分析(二) 作者机构: 上海AI Lab, 上海交通大学, 香港大学, 浙江大学, 香港中文大学 论文主题: 人形机器人…...
日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする
日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする 1、前言(1)情况说明(2)工程师的信仰2、知识点(1) にする1,接续:名词+にする2,接续:疑问词+にする3,(A)は(B)にする。(2)復習:(1)复习句子(2)ために & ように(3)そう(4)にする3、…...

蓝牙 BLE 扫描面试题大全(2):进阶面试题与实战演练
前文覆盖了 BLE 扫描的基础概念与经典问题蓝牙 BLE 扫描面试题大全(1):从基础到实战的深度解析-CSDN博客,但实际面试中,企业更关注候选人对复杂场景的应对能力(如多设备并发扫描、低功耗与高发现率的平衡)和前沿技术的…...
质量体系的重要
质量体系是为确保产品、服务或过程质量满足规定要求,由相互关联的要素构成的有机整体。其核心内容可归纳为以下五个方面: 🏛️ 一、组织架构与职责 质量体系明确组织内各部门、岗位的职责与权限,形成层级清晰的管理网络…...
spring:实例工厂方法获取bean
spring处理使用静态工厂方法获取bean实例,也可以通过实例工厂方法获取bean实例。 实例工厂方法步骤如下: 定义实例工厂类(Java代码),定义实例工厂(xml),定义调用实例工厂ÿ…...

项目部署到Linux上时遇到的错误(Redis,MySQL,无法正确连接,地址占用问题)
Redis无法正确连接 在运行jar包时出现了这样的错误 查询得知问题核心在于Redis连接失败,具体原因是客户端发送了密码认证请求,但Redis服务器未设置密码 1.为Redis设置密码(匹配客户端配置) 步骤: 1).修…...