【算法】堆排序 详解

堆排序 详解
- 堆排序
- 代码实现
排序: 排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作。
稳定性: 假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次序保持不变,即在原序列中, r[i] = r[j], 且 r[i] 在 r[j] 之前,而在排序后的序列中, r[i] 仍在 r[j] 之前,则称这种排序算法是稳定的;否则称为不稳定的。
(注意稳定排序可以实现为不稳定的形式, 而不稳定的排序实现不了稳定的形式)

内部排序: 数据元素全部放在内存中的排序。
外部排序: 数据元素太多不能同时放在内存中,根据排序过程的要求不能在内外存之间移动数据的排序。
堆排序
堆排序 (Heapsort) 是指利用堆积树(堆)这种数据结构所设计的一种排序算法,它是选择排序的一种。它是通过堆来进行选择数据。需要注意的是排升序要建大堆,排降序建小堆。
为什么排升序建大堆?
- 因为假如排升序建小堆的话, 那么 我们只能得到最小的数字这一个, 同时堆的结构已经被破坏了, 因为我们直到最小值之后肯定要把这个最小值拿出来, 让剩下的元素进行排序, 也就是说堆的根节点下标要从 1 开始了, 这样就需要重新建堆了, 而建堆的时间复杂度是 O(N), 这样每选出来一个数, 就建一次堆, 总的时间复杂度就是 O(N*N) 了, 完全没有用上堆的优势。
- 但是假如排升序建大堆的话, 每次我们能选出来最大的值, 然后把它与最后位置的元素进行交换, 那么堆的根节点的位置还是从 0 开始,唯一可能不满足堆的性质情况就是 根节点小于 其他节点, 此时只需要 将根节点进行向下调整算法即可,不用重新建堆 。
友情链接:堆的讲解
基本思想: 建堆和排序。
- 建堆(Heapify):
- 首先,将待排序的数组视为一个完全二叉树。
- 从数组的最后一个非叶子节点开始,逐个向前处理,对每个节点执行向下调整算法(将较大的元素交换到子节点的位置),直至整个数组构建成一个最大堆(Max Heap)或最小堆(Min Heap)。
- 最大堆的特点是每个节点的值都大于或等于其子节点的值,最小堆则相反,每个节点的值都小于或等于其子节点的值。
- 排序:
- 一旦构建好堆,堆顶元素就是最大(最小)元素。
- 将堆顶元素与堆的最后一个元素交换位置,然后将堆的大小减 1。
- 对新的堆顶元素执行一次下沉操作,将新的最大(最小)元素浮到堆顶。
- 重复上述步骤,直到堆的大小为 1,排序完成。
堆排序的关键在于如何维护堆的性质,即使交换元素后,仍然保持堆的性质。这是通过向下调整操作来实现的,确保每次交换后最大(最小)元素移到堆的顶部。

代码实现
public static void heapSort(int[] arr) {int len = arr.length;// 排升序// 建大堆// 从最后一个非叶子节点进行向下调整for (int i = (len-1-1)/2; i >= 0; i--) {shiftDown(arr, i, len);}// 排序// 从最后一个节点开始与第一个节点交换位置for (int i = len-1; i > 0; i--) {// 最大值放到最后面swap(arr, 0, i);// 交换完成后重新调整堆, 注意 此时堆的大小要 - 1, 但是 这正好与 i 相同, 所以直接使用了 ishiftDown(arr, 0, i);}}/*** 向下调整算法*/public static void shiftDown(int[] arr, int index, int len) {int parent = index;int child = parent * 2 + 1;// 一直向下调整至符合堆 或者 至最后一个节点while (child < len) {if (child+1 < len && arr[child+1] > arr[child]) {child++;}if (arr[child] > arr[parent]) {// 交换节点swap(arr, parent, child);// 继续向下调整parent = child;child = parent * 2 + 1;} else {// 调整完成break;}}}
总结:
- 时间复杂度: O(N*logN)
- 空间复杂度: O(1)
- 是不稳定排序: 向下调整过程中, 可能相对顺序发生变化
- 对数据不敏感: 不管原本数据怎么分布, 都要先建堆, 然后排序
- 相对于快速排序和归并排序,堆排序通常效率较低,因为它的数据访问模式不够连续,可能导致缓存不命中
以上就是对堆排序的讲解, 希望能帮到你 !
评论区欢迎指正 !
相关文章:
【算法】堆排序 详解
堆排序 详解 堆排序代码实现 排序: 排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作。 稳定性: 假定在待排序的记录序列中,存在多个具有相同的关键字的记录,…...
解决Maven依赖下载问题:从阿里云公共仓库入手
🌷🍁 博主猫头虎(🐅🐾)带您 Go to New World✨🍁 🦄 博客首页——🐅🐾猫头虎的博客🎐 🐳 《面试题大全专栏》 🦕 文章图文…...
【Java基础】学习笔记2 - 数组运算符与main方法
目录 多态数组运算符hashCodefinalize 方法 第三阶段类变量类方法main 方法代码块单例模式饥饿式懒汉式 多态数组 顾名思义,就是在一个数组内体现多态 public class PolyArrDemo {public static void main(String[] args) {// 定义多态数组Fruit[] fruits new Fr…...
stable diffusion实践操作-复制-清空-保存提示词
系列文章目录 stable diffusion实践操作 stable diffusion实践操作-webUI教程 提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 系列文章目录前言一、右上生成图标附近按钮介绍1. 箭头介绍(复现别人的…...
【Spring 事务和事务传播机制】
目录 1 事务概述 1.1 为什么需要事务 1.2 事务的特性 1.3 Spring 中事务的实现 2 Spring 声明式事务 2.1 Transactional 2.2 Transactional 的作用范围 2.3 Transactional 的各种参数 2.3.1 ioslation 2.4 事务发生了异常,也不回滚的情况 异常被捕获时 3 事务的传…...
【爬虫】实验项目二:模拟登录和数据持久化
目录 一、实验目的 二、实验预习提示 三、实验内容 实验要求 基本要求: 改进要求A: 改进要求B: 四、实验过程 基本要求: 源码如下: 改进要求A: 源码如下: 改进要求B: 源码如下&…...
图文版:以太网二层接口类型(含配套习题)
常见的以太网二层接口类型包括以下三种: 一、Access接口 access链路类型端口,一种交换机的主干道模式,2台交换机的2个端口之间是否能够建立干道连接,取决于这2个端口模式的组合。 Access端口在收到以太网帧后打开VLAN标签&#…...
生信豆芽菜-机器学习筛选特征基因
网址:http://www.sxdyc.com/mlscreenfeature 一、使用方法 1、准备数据 第一个文件:特征表达数据 第二个文件:分组信息,第一列为样本名,第二列为患者分组 第三个文件:分析基因名 2、选择机器学习的方…...
v-html富文本里面的图片设置宽高不起作用的原因
把scoped去掉...
pdf文档怎么压缩小一点?文件方法在这里
在日常工作和生活中,我们经常会遇到需要上传或者发送pdf文档的情况。但是,有时候pdf文档的大小超出了限制,需要我们对其进行压缩。那么,如何将pdf文档压缩得更小一点呢?下面,我将介绍三种方法,让…...
CMD关闭占用端口
1. netstat -ano | findstr :xxxx 2. taskkill /pid xxxx 3. 强制关闭taskkill/F /pid xxxx...
复制粘贴是怎么实现的
在上面的代码中,command 和 select 是自定义的函数。它们的作用如下: 实现复制粘贴的思路: 创建一个 textarea 标签将 textarea 移出可视区域给这个 textarea 赋值将这个 textarea 标签添加到页面中调用 textarea 的 select 方法调用 docum…...
mybatisplus多租户原理略解
概述 当前mybatisPlus版本 <dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.3.2</version> </dependency>jdk版本:17 springboot版本:…...
Spring整合RabbitMQ-配制文件方式-1-消息生产者
Spring-amqp是对AMQP的一些概念的一些抽象,Spring-rabbit是对RabbitMQ操作的封装实现。 主要有几个核心类RabbitAdmin、RabbitTemplate、SimpleMessageListenerContainer等 RabbitAdmin类完成对Exchange、Queue、Binding的操作,在容器中管理 了RabbitA…...
Python Opencv实践 - 凸包检测(ConvexHull)
import cv2 as cv import numpy as np import matplotlib.pyplot as pltimg cv.imread("../SampleImages/stars.png") plt.imshow(img[:,:,::-1])img_contour img.copy() #得到灰度图做Canny边缘检测 img_gray cv.cvtColor(img_contour, cv.COLOR_BGR2GRAY) edges…...
IP网络广播系统有哪些优点
IP网络广播系统有哪些优点 IP网络广播系统有哪些优点? IP网络广播系统是基于 TCP/IP 协议的公共广播系统,采用 IP 局域网或 广域网作为数据传输平台,扩展了公共广播系统的应用范围。随着局域网络和 网络的发展 , 使网络广播的普及变为可能 …...
【LeetCode】83. 删除排序链表中的重复元素
83. 删除排序链表中的重复元素(简单) 方法:一次遍历 思路 由于给定的链表是排好序的,因此重复的元素在链表中出现的位置是连续的,因此我们只需要对链表进行一次遍历,就可以删除重复的元素。 从指针 cur 指…...
【大数据】Flink 详解(七):源码篇 Ⅱ
本系列包含: 【大数据】Flink 详解(一):基础篇【大数据】Flink 详解(二):核心篇 Ⅰ【大数据】Flink 详解(三):核心篇 Ⅱ【大数据】Flink 详解(四…...
stable diffusion实践操作-SD原理
系列文章目录 本文专门开一节写SD原理相关的内容,在看之前,可以同步关注: stable diffusion实践操作 文章目录 系列文章目录前言一、原理说明1.1、出图原理1.1.1 AI画画不是和人一样,从0开始,而是一个去噪点的过程&am…...
C++ Primer Plus第十三章编程练习答案
1,以下面的类声明为基础: // base class class Cd{ // represents a CD disk private: char performers[50] ; char label[20]; int selections;// number of selections double playtime; // playing time in minutes public: Cd(char * sl,char * s2,int n,double…...
观成科技:隐蔽隧道工具Ligolo-ng加密流量分析
1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具,该工具基于TUN接口实现其功能,利用反向TCP/TLS连接建立一条隐蔽的通信信道,支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式,适应复杂网…...
Cursor实现用excel数据填充word模版的方法
cursor主页:https://www.cursor.com/ 任务目标:把excel格式的数据里的单元格,按照某一个固定模版填充到word中 文章目录 注意事项逐步生成程序1. 确定格式2. 调试程序 注意事项 直接给一个excel文件和最终呈现的word文件的示例,…...
1688商品列表API与其他数据源的对接思路
将1688商品列表API与其他数据源对接时,需结合业务场景设计数据流转链路,重点关注数据格式兼容性、接口调用频率控制及数据一致性维护。以下是具体对接思路及关键技术点: 一、核心对接场景与目标 商品数据同步 场景:将1688商品信息…...
【ROS】Nav2源码之nav2_behavior_tree-行为树节点列表
1、行为树节点分类 在 Nav2(Navigation2)的行为树框架中,行为树节点插件按照功能分为 Action(动作节点)、Condition(条件节点)、Control(控制节点) 和 Decorator(装饰节点) 四类。 1.1 动作节点 Action 执行具体的机器人操作或任务,直接与硬件、传感器或外部系统…...
JDK 17 新特性
#JDK 17 新特性 /**************** 文本块 *****************/ python/scala中早就支持,不稀奇 String json “”" { “name”: “Java”, “version”: 17 } “”"; /**************** Switch 语句 -> 表达式 *****************/ 挺好的ÿ…...
Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信
文章目录 Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信前言一、网络通信基础概念二、服务端与客户端的完整流程图解三、每一步的详细讲解和代码示例1. 创建Socket(服务端和客户端都要)2. 绑定本地地址和端口&#x…...
C++ 设计模式 《小明的奶茶加料风波》
👨🎓 模式名称:装饰器模式(Decorator Pattern) 👦 小明最近上线了校园奶茶配送功能,业务火爆,大家都在加料: 有的同学要加波霸 🟤,有的要加椰果…...
MySQL 索引底层结构揭秘:B-Tree 与 B+Tree 的区别与应用
文章目录 一、背景知识:什么是 B-Tree 和 BTree? B-Tree(平衡多路查找树) BTree(B-Tree 的变种) 二、结构对比:一张图看懂 三、为什么 MySQL InnoDB 选择 BTree? 1. 范围查询更快 2…...
Spring Security 认证流程——补充
一、认证流程概述 Spring Security 的认证流程基于 过滤器链(Filter Chain),核心组件包括 UsernamePasswordAuthenticationFilter、AuthenticationManager、UserDetailsService 等。整个流程可分为以下步骤: 用户提交登录请求拦…...
用鸿蒙HarmonyOS5实现中国象棋小游戏的过程
下面是一个基于鸿蒙OS (HarmonyOS) 的中国象棋小游戏的实现代码。这个实现使用Java语言和鸿蒙的Ability框架。 1. 项目结构 /src/main/java/com/example/chinesechess/├── MainAbilitySlice.java // 主界面逻辑├── ChessView.java // 游戏视图和逻辑├──…...
