【算法】堆排序

1. 堆排序简介

堆排序heapsort)是由 J. W. J. Williams 于 1964 年发明的。是一种基于比较的排序算法,和选择排序一样,堆排序将数据序列分为已排序区域未排序区域两部分。通过从未排列区域中获取最大元素并将其插入已排序区域,迭代这个操作来缩小未排序区域。与选择排序不同的是,堆排序不会对未排序区域进行线性扫描,而是通过维护堆中未排序区域的数据结构以到达高效获取最大元素的目的。堆排序的平均时间复杂度为 O ( n log ⁡ n ) O{\left(n\log n\right)} O(nlogn),空间复杂度为 O ( 1 ) O{\left(1\right)} O(1)(原地算法)。

2. 原理

将数组转化为最大堆Max-Heap),根结点的键值是所有堆结点键值中最大者的二叉树。
Array [ p a r e n t ( i ) ] ≥ Array [ i ] {\text{Array}}{\left[parent{\left(i\right)} \right]}\ge{\text{Array}}{\left[i\right]} Array[parent(i)]Array[i]
接着重复取出最大堆中的最大值(即根节点值)插入已排序区域,并维护残余堆的最大堆特性就可完成排序。

3. 步骤

  1. 建立最大堆
  2. 取出最大值(即根节点),并维护残余堆。
  3. 递归步骤2,完成排序
Yes
No
开始
建立最大堆
获取根值?
维护残余堆
结束

3.1 数组索引和堆节点位置的关系

数组如下:

012345678
2634438547153626

可以看成

[0]=26
[1]=3
[2]=44
[3]=38
[4]=5
[5]=47
[6]=15
[7]=36
[8]=26

由此上可以看出:

  1. 数组 [ i ] {\left[i\right]} [i]的左子节点的位置为 2 × i + 1 2\times i+1 2×i+1
  2. 数组 [ i ] {\left[i\right]} [i]的右子节点的位置为 2 × i + 2 2\times i+2 2×i+2
  3. 数组 [ i ] {\left[i\right]} [i]的父节点的位置为
    • i i i为偶数则父节点位置为 i − 2 2 \frac{i-2}{2} 2i2
    • i i i为基数则父节点位置为 i − 1 2 \frac{i-1}{2} 2i1
    • 可以简化为数组 [ i ] {\left[i\right]} [i]的父节点位置为 ⌊ i − 1 2 ⌋ \lfloor \frac{i-1}{2}\rfloor 2i1

3.2 建立最大堆

从数组后面向前扫描并调整堆满足最大堆的特性:

[0]=26
[1]=3
[2]=44
[3]=38
[4]=5
[5]=47
[6]=15
[7]=36
[8]=26

数组中[7]=36 和 [8]=26 都满足小于父节点 [3]=38;继续向前扫描得 [6]=15 也满足小于父节点 [2]=44;继续:

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

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

相关文章

2024年华为OD机试真题-二叉树的广度优先遍历-Python-OD统一考试(C卷)

题目描述: 有一棵二叉树,每个节点由一个大写字母标识(最多26个节点)。现有两组字母,分别表示后序遍历(左孩子->右孩子->父节点)和中序遍历(左孩子->父节点->右孩子)的结果,请输出层次遍历的结果。 输入描述: 输入为两个字符串,分别是二叉树的后续遍历和…

LeetCode第三天(645. 错误的集合)

集合 s 包含从 1 到 n 的整数。不幸的是,因为数据错误,导致集合里面某一个数字复制了成了集合里面的另外一个数字的值,导致集合 丢失了一个数字 并且 有一个数字重复 。 给定一个数组 nums 代表了集合 S 发生错误后的结果。 请你找出重复出…

npm install jsencrypt爆错

报错: npm install jsencrypt npm ERR! code CERT_HAS_EXPIRED npm ERR! errno CERT_HAS_EXPIRED npm ERR! request to https://registry.npm.taobao.org/jsencrypt failed, reason: certificate has expired npm ERR! A complete log of this run can be found in: C:\Users…

C++ explicit隐式类型转换

单参数构造函数支持隐式类型的转换 什么意思? 简单来理解就是: 一个类对象的构造函数的参数只有一个,就可以直接进行赋值传参 例如构造函数的参数为int,且只有一个int 就可以直接将int类型的整型数据转换成类对象 也就是说从int类…

Unity构建详解(3)——SBP的依赖计算

【前置知识】 先要搞清楚Asset和Object的关系,可以简单理解为一个Asset对应多个Object。 unity自定义的Asset也要有一个存储的标准,其采用的是YAML,我们看到的所有Unity自定义的Asset格式,例如.prefab(预制体&#x…

研华工控机610L学习笔记2:visualstudio与第一个C#程序

今日继续学习工控机 C# 编程相关知识: 这篇结束后我将先进行一段时间的C#的学习研究,并写一些C#的笔记 后续再更新工控机编程设计相关 目录 1、安装visualstudio: 2、创建第一个C#程序: 3、寻找C#解决方案源文件: …

linux之zabbix自定义监控

zabbix基本配置见:写文章-CSDN创作中心https://mp.csdn.net/mp_blog/creation/editor/136783672 自定义监控规则 命令为who | wc -l 显示为2,主机一个,mobaxterm一个,思路是开启3个终端,让主机的zabbix服务自动检测1…

B端设计:如何让UI组件库成为助力,而不是阻力。

首发2023-09-24 15:42贝格前端工场 Hi,我是大千UI工场,网上的UI组件库琳琅满目,比如elementUI、antdesign、iview等等,甚至很多前端框架,也出了很多UI组件,如若依、Layui、bootstrap等等,作为U…

I/O多路复用:select/poll/epoll

最基本的 Socket 模型 要想客户端和服务器能在网络中通信,那必须得使用 Socket 编程,它是进程间通信里比较特别的方式,特别之处在于它是可以跨主机间通信。 Socket 的中文名叫作插口,咋一看还挺迷惑的。事实上,双方要…

基于SpringBoot图书进销存管理系统

采用技术 基于SpringBoot图书进销存管理系统的设计与实现~ 开发语言:Java 数据库:MySQL 技术:SpringBootMyBatis 工具:IDEA/Ecilpse、Navicat、Maven 页面展示效果 用户信息管理 图书类型管理 商品退货管理 客户信息管理 图…

软件测试相关内容第六弹 -- 测试实战

写在前:hello大家早中晚上好!这里是西西,前面我们已经学习了关于测试相关基础的介绍,点击链接直达前方内容~ 测试内容博客链接初识软件测试点击跳转软件测试相关概念点击跳转测试生命周期、BUG、测试大体流程点击跳转测试用例、测…

技术整理:SpringBoot+Redis+lua脚本防止超卖

SpringBootredislua 防止超卖 一、背景 工作中遇到了有人用 RedisTemplate 的 increment去做总库存的加减,但是这种方式是保证不了原子性的还是会超卖。 redis 是可以保证原子性,但是 RedisTemplate 里面的方法去调用redis是不能保证原子性 二、优化…

数据结构·排序

1. 排序的概念及运用 1.1 排序的概念 排序:排序是将一组“无序”的记录序列,按照某个或某些关键字的大小,递增或递减归零调整为“有序”的记录序列的操作 稳定性:假定在待排序的记录序列中,存在多个具有相同关键字的记…

在MySQL中,如何处理主键冲突的问题?

在MySQL中处理主键冲突的问题时,有几种常用的方法: 1. INSERT IGNORE - 使用 INSERT IGNORE 语句插入数据时,如果主键冲突(即主键已经存在于表中),MySQL将忽略此次插入操作,不会更改现有记录&am…

day03_mysql_课后练习 - 参考答案

文章目录 day03_mysql_课后练习mysql练习题第1题第2题第3题第4题第5题 day03_mysql_课后练习 mysql练习题 第1题 案例: 1、创建一个数据库:day03_test01_school 2、创建如下表格 表1 Department表的定义 字段名字段描述数据类型主键外键非空唯一D…

Docker 笔记(七)--打包软件生成镜像

目录 1. 背景2. 参考3. 文档3.1 使用docker container commit命令构建镜像3.1.1 [Docker官方文档-docker container commit](https://docs.docker.com/reference/cli/docker/container/commit/)Description(概述)Options(选项)Exa…

【Redis】Redis特性

Redis 认识redisRedis特性在内存中存储数据可编程可扩展性持久化Clustering高可用性 认识redis Redis,英文全称是Remote Dictionary Server(远程字典服务),是一个开源的使用ANSIC语言编写、支持网络、可基于内存亦可持久化的日志…

【JAVA】封装与包

。何为封装呢?简单来说 就是套壳屏蔽细节 封装:将数据和操作数据的方法进行有机结合,隐藏对象的属性和实现细节,仅对外公开接口来和对象进行 交互 访问限定符 public:可以理解为一个人的外貌特征,谁都可以…

【webpack】----错误解决【Cannot read properties of undefined (reading ‘tap‘)】

1. 报错场景 安装 webpack-obfuscator 后,进行 js 代码混淆编译的时候报错。 2. 报错截图 3. 错误原因 通常是由于版本不兼容或配置错误引起的。 4. 查询本地 webpack 版本 4.1 查询命令 npm 查询 npm view webpack versionyarn 查询 yarn info webpack ver…

Java学习笔记 | JavaSE基础语法 | 04 | 数组

文章目录 0.前言1.数组2.数组声明2.1 数组定义2.2 数组初始化1.静态初始化2.动态初始化3.区别4.数组的默认初始化值: 2.3 数组名 3.访问数组3.1 索引3.2 访问数组3.3 length属性 4.数组常见问题5.数组内存分析5.1 内存分配5.2 数组内存分配 6.数组的练习练习1&#…