漫画:什么是堆排序?

【数据结构入门】堆(Heap) 文章目录一、堆的结构及实现(重要)1.1 二叉树的顺序结构1.2 堆的概念及结构1.3 堆的实现1.3.1 堆的向下调整算法1.3.2 **向下调整算法的时间复杂度**1.3.3 堆的创建(向下调整)1.3.4 堆排序1.3.5 建堆的时间复杂度二、堆的相关接口实现(以大堆为例)2.1 堆的初始化2.2 堆的销毁2.3 堆的插入2.4 堆的删除2.5 获取堆顶元素2.6 堆的判空2.7 拓展1:找出堆中前k个最大元素2.8 拓展2:堆的创建(向上调整) 一、堆的结构及实现(重要) 1.1 二叉树的顺序结构 阅读详情

在上一篇漫画中,小灰介绍了 二叉堆 这样一种强大的数据结构:

 

漫画:什么是二叉堆?(修正版)

 

那么,这个二叉堆怎样来使用呢?我们这一期将会详细讲述。

 

 

 

 

 

 

让我们回顾一下二叉堆和最大堆的特性:

 

1.二叉堆本质上是一种完全二叉树

2.最大堆的堆顶是整个堆中的最大元素

 

当我们删除一个最大堆的堆顶(并不是完全删除,而是替换到最后面),经过自我调节,第二大的元素就会被交换上来,成为最大堆的新堆顶。

 

 

 

正如上图所示,当我们删除值为10的堆顶节点,经过调节,值为9的新节点就会顶替上来;当我们删除值为9的堆顶节点,经过调节,值为8的新节点就会顶替上来.......

 

由于二叉堆的这个特性,我们每一次删除旧堆顶,调整后的新堆顶都是大小仅次于旧堆顶的节点。那么我们只要反复删除堆顶,反复调节二叉堆,所得到的集合就成为了一个有序集合,过程如下:

 

 

删除节点9,节点8成为新堆顶:

 

 

 

删除节点8,节点7成为新堆顶:

 

 

 

删除节点7,节点6成为新堆顶:

 

 

 

删除节点6,节点5成为新堆顶:

 

 

 

删除节点5,节点4成为新堆顶:

 

 

 

删除节点4,节点3成为新堆顶:

 

 

 

删除节点3,节点2成为新堆顶:

 

 

 

到此为止,我们原本的最大堆已经变成了一个从小到大的有序集合。之前说过二叉堆实际存储在数组当中,数组中的元素排列如下:

 

 

 

由此,我们可以归纳出堆排序算法的步骤:

 

1. 把无序数组构建成二叉堆。

2. 循环删除堆顶元素,移到集合尾部,调节堆产生新的堆顶。

 

 

 

 

 

public class HeapSort {
 
/**

* 下沉调整

* @param array     待调整的堆

* @param parentIndex    要下沉的父节点

* @param parentIndex    堆的有效大小

*/

public static void downAdjust(int[] array, int parentIndex, int length) {

   // temp保存父节点值,用于最后的赋值

   int temp = array[parentIndex];

   int childIndex = 2 * parentIndex + 1;

   while (childIndex < length) {

       // 如果有右孩子,且右孩子大于左孩子的值,则定位到右孩子

       if (childIndex + 1 < length && array[childIndex + 1] > array[childIndex]) {

           childIndex++;

       }

       // 如果父节点小于任何一个孩子的值,直接跳出

       if (temp >= array[childIndex])

           break;

       //无需真正交换,单向赋值即可

       array[parentIndex] = array[childIndex];

       parentIndex = childIndex;

       childIndex = 2 * childIndex + 1;

   }

   array[parentIndex] = temp;

}



/**

* 堆排序

* @param array     待调整的堆

*/

public static void heapSort(int[] array) {

   // 1.把无序数组构建成二叉堆。

   for (int i = (array.length-2)/
2; i >= 0; i--) {

       downAdjust(array, i, array.length);

   }

   System.out.println(Arrays.toString(array));

   // 2.循环删除堆顶元素,移到集合尾部,调节堆产生新的堆顶。

   for (int i = array.length - 1; i > 0; i--) {

       // 最后一个元素和第一元素进行交换

       int temp = array[i];

       array[i] = array[0];

       array[0] = temp;

       // 下沉调整最大堆

       downAdjust(array, 0, i);

   }

}


public static void main(String[] args) {

   int[] arr = new int[] {1,3,2,6,5,7,8,9,10,0};

   heapSort(arr);

   System.out.println(Arrays.toString(arr));

}

}

 

 

 

 

二叉堆的节点下沉调整(downAdjust 方法)是堆排序算法的基础,这个调节操作本身的时间复杂度是多少呢?

 

假设二叉堆总共有n个元素,那么下沉调整的最坏时间复杂度就等同于二叉堆的高度,也就是O(logn)。

 

我们再来回顾一下堆排序算法的步骤:

 

1. 把无序数组构建成二叉堆。

2. 循环删除堆顶元素,移到集合尾部,调节堆产生新的堆顶。

 

第一步,把无序数组构建成二叉堆,需要进行n/2次循环。每次循环调用一次 downAdjust 方法,所以第一步的计算规模是  n/2 * logn,时间复杂度O(nlogn)。

 

第二步,需要进行n-1次循环。每次循环调用一次 downAdjust 方法,所以第二步的计算规模是 (n-1) * logn ,时间复杂度 O(nlogn)。

 

两个步骤是并列关系,所以整体的时间复杂度同样是 O(nlogn)。

 

 

 

 

 

 

 

 

 

 

 

 

 

—————END—————

什么是堆排序 堆排序是使用二叉堆这样强大的数据结构来实现的排序 回顾:二叉堆的特性 二叉堆本质上是一种完全二叉树 最大堆(最小堆)的堆顶是整个堆中的最大(最小)元素 原理 当我们删除一个最小堆的堆顶的时候是把堆顶的元素删除,并把最后一个元素拿到堆顶 这时如果我们不把堆顶元素删除,而是把堆顶和最后一个元素替换,并把堆的有效长度减1 之后向下调整67,使堆保持稳定 重复上述操作将现在有效长度内的最后... 阅读详情

相关推荐

# 多用户 JupyterHub 配置教程(通用 Linux 服务器版)

以上即是通用 Linux 服务器上的多用户 JupyterHub 实战配置。从安装认证与 Spawner 选择自动创建系统用户到反代与运维,覆盖了小团队到中等规模的主流场景。根据团队增长与合规要求,你可以进一步引入、统一身份源(LDAP/OAuth2/Keycloak)与资源配额治理,平滑演进到企业级部署。

数字化老司机 1288

内存学习——堆(heap)

/自定义1024字节内存的数组,模拟堆//指向堆数组可用空间的首地址void *my_malloc(int size) //自定义malloc函数//记录开辟空间的首地址//malloc的空间大小//返回开辟空间的首地址void my_free(void *buf) //可用自定义malloc函数,但是无法自定义free函数,后面分析原因/* err */int i;//使用自定义的malloc函数在自定义堆数组中开辟100字节空间for (i = 0;i < 26;i++)

studyingdda的博客 3321

XTDrone——ALOAM与3D激光雷达三维SLAM(处理没有点云和坐标系报错的问题)

本文介绍了XTDrone中配置如何在三维环境中使用A-LOAM算法配合velodyneHDL32激光雷达包括依赖包安装、代码修改和PX4系统配置,以及相关报错细节的注意事项。

weixin_45390670的博客 1325

堆(heap)和栈(stack)区别

https://www.cnblogs.com/yechanglv/p/6941993.html 堆和栈的区别 一、预备知识—程序的内存分配 一个由c/C++编译的程序占用的内存分为以下几个部分 1、栈区(stack)—由编译器自动分配释放,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。 2、堆区(heap)—一般由程序员分配释放,若程序员不释放,程序结束时可能由OS回收。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表,呵呵。 3、全局区(静态区)(static)...

二进制模----细微行动改变影响世界 1865

企业固定资产管理的SAP实战:FICO模块配置与折旧范围设置详解

本文深入解析了SAP FICO模块中固定资产会计配置的核心实践,重点阐述了折旧范围的设计哲学与配置逻辑。通过详解折旧表、折旧范围、资产分类及折旧码等关键配置步骤,指导企业如何搭建满足多会计准则(如CAS、IFRS)与税务要求的资产管理体系,实现资产购置、折旧计提与报废清理的自动化与精准化。

wdx01234567的博客 727

晶振匹配电容容值计算方法

在使用晶振时,应仔细参考晶振规格书,以确保正确选择匹配电容,从而获得稳定和精准的时钟源。

aidi1111的博客 4653

【数据结构】堆(Heap)

就可以建成一个 (大 / 小) 堆。我们把数组中的第一个元素看作是一个堆剩余的元素依次插入到这个堆中。这跟堆的插入接口原理相同,就是向上调整。如果堆的创建过程使用向上调整算法,那么每次插入一个新元素时都需要进行一次向上调整操作,以确保新插入的元素能够满足堆的性质。【时间复杂度】假设堆中已经有 n 个元素,那么堆的高度 h = log₂(n+1),在插入一个新元素的过程中,需要进行的向上调整操作次数为 h-1,则 h = log₂(n+1) - 1,

Elena's Blog 6180

Proteus快速入门(最详细教程)

Proteus 是一款用于嵌入式单片机仿真的软件,用于在打PCB板之前对软件程序和硬件电路的正确性进行仿真验证。1.所以Proteus一般会和Keil软件进行联合仿真,在Proteus中绘制系统的电路图,在Keil软件中编写对应的程序后生成Hex文件。2.Proteus的仿真结果仅供参考,只能在一定程度上验证系统的可能性。实际实物系统还需要进行进一步的调试。以上即为本次分享的Proteus入门教程的全部内容,希望可以能够帮助到各位道友。

ediykk的博客 15万+

Heap算法详解

本文主要介绍了STL中四种heap算法,包括make_heap(), sort_heap(),pop_heap(),push_heap()

Keep Moving~ 3935

GPU核心性能指标

内存科普 CPU缓存分为三类,一级缓存(L1)、二级缓存(L2)和三级缓存(L3)。CPU在实际数据读取中重要的却是一级缓存,因为一级缓存速度最快,二级缓存其次,三级缓存最慢,只是三级缓存的容量最大。 DDR1,DDR2,DDR3内存条(DDR是Double Data Rate双倍速率同步动态随机存储器的英文缩写)就是俗称的一二三代内存条。这三种内存条工艺不同,接口不同,性能不同,互不兼容。要区分它们,也不难。内存条可以用在CPU内存或者GPU显存中。比如 the NVIDIA Tesla M2050 GP

Charles Ren's Tech Blog 2万+

CGAL-5.6的安装与编译(Win10+vs2022+CGAL-5.6+Boost1.82.0)

CGAL是Computational Geometry Algorithms Library(计算几何算法库)的缩写,C++的高效算法库。CGAL只是一个头文件库(从5.0版本开始),这意味着CGAL无需编译,只需安装好CGAL的依赖项即可。CGAL5.6。

baidu_34931359的博客 3902

漫画:什么是堆排序算法?

面试官:写一个堆排吧堆排是基于堆的一种排序算法,对于堆的了解,请看(如果对堆的插入和删除不清楚,强烈建议先看堆),今天我们聊聊堆排的思想,复杂度以及稳定性。

帅地 339

SAP UI5 应用开发教程的学习目录 - 循序渐进,由浅入深,适合不同水平的 SAP UI5 开发人员

笔者在业余时间设计了这份 SAP UI5 学习教程,把开发一个完整的 SAP UI5 应用的流程,拆分成若干个步骤,力求每个步骤里,把涉及到的知识点都涵盖到。建议零基础或者对 SAP UI5 知之甚少的 SAP UI5 初学者,按照顺序从第一个步骤开始循序渐进地学习,把这些代码下载到本地,配合教程的文字讲解,自己动手,以加深理解。 对于已经有一定基础的 SAPUI5 开发人员,可以通过本文的目录,跳过前面一部分比较基础的章节,直接挑选对自己工作项目有关,或者包含某些知识点自己尚未掌握的章节来有针对性地学习。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 3万+

堆排序时间复杂度_漫画:什么是堆排序?

在上一篇漫画中,小灰介绍了 二叉堆 这样一种强大的数据结构:漫画:什么是二叉堆?(修正版)那么,这个二叉堆怎样来使用呢?我们这一期将会详细讲述。让我们回顾一下二叉堆和最大堆的特性:1.二叉堆本质上是一种完全二叉树2.最大堆的堆顶是整个堆中的最大元素当我们删除一个最大堆的堆顶(并不是完全删除,而是替换到最后面),经过自我调节,第二大的元素就会被交换上来,成为最大堆的新堆顶。正如上图所示,当我们删除值...

weixin_39957068的博客 148

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

数据结构和算法入门

算法与数据结构 数据结构 这是我第一次写博客,从看这本书开始吧 漫画算法:小灰的算法之旅,大家一起加油 排序 算法的类型: 1.冒泡排序 2.鸡尾酒排序 3.快速排序 4.堆排序 全新的界面设计 ,将会带来全新的写作体验; 在创作中心设置你喜爱的代码高亮样式,Markdown 将代码片显示选择的高亮样式 进行展示; 增加了 图片拖拽 功能,你可以将本地的图片直接拖拽到编辑区域直接展示; 全新的 KaTeX数学公式 语法; 增加了支持甘特图的mermaid语法1 功能; 增加了 多屏幕编辑 Markdown

littlemanv的博客 141

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

漫画算法笔记 堆排序

漫画算法笔记 堆排序 #include <iostream> #include <stdlib.h> #include <vector> #include <iterator> #include <algorithm> using namespace std; //下沉调整 template<typename T> void downAdjust(vector<T> &vec, int parentIndex, i

qq_36333986的博客 188

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

漫画:“排序算法” 大总结

冒泡排序:漫画:什么是冒泡排序?选择排序:漫画:什么是选择排序?插入排序:漫画:什么是插入排序?此外还有冒泡排序的变种,鸡尾酒排序:漫画:什么是鸡尾酒排序?第三梯队的排序算法有什么共同点...

程序员小灰的博客 6649

堆排序总结

本文内容来源于《漫画算法》和数据结构教材 这里提到的堆是一个二叉堆,本质上是一颗完全二叉树。堆排序只需要一个记录大小的辅助空间。 1.java实现 /** * 下沉调整 * @param arr 待调整的堆 * @param parentIndex 要下沉的父节点下标 * @param length 堆的有效大小(一般指存储堆的数组长度) */ void downAdjus...

ximen250的专栏 315

《漫画算法》终于出电子书了!

今年5月,小灰出版了《漫画算法》这本纸质书。在今年年中,本书获得【京东科技新书畅销榜】第1名,【京东科技畅销榜】第4名,非常感谢大家的支持!但是有一点美中不足,小灰的这本...

程序员小灰的博客 1万+

漫画算法:小灰的算法之旅(读书笔记)

感兴趣的可以关注一下微信公众号:程序员小灰 内容简介 《漫画算法:小灰的算法之旅》通过虚拟的主人公小灰的心路历程,用漫画的形式讲述了算法和数据结构的基础知识、复杂多变的算法面试题目及算法的实际应用场景。 第1章 介绍了算法和数据结构的相关概念,算法是什么,数据结构又是什么,用途是什么,如何分析时间复杂度,如何分析空间复杂度。 第2章 介绍了最基本的数据结构,包括数组、链表、栈、队列、哈希表的概...

夏曦 2164

漫画算法python版下载_漫画算法:小灰的算法之旅(Python篇)

书名:漫画算法:小灰的算法之旅(Python篇)定价:79.0ISBN:9787121382789作者:魏梦舒版次:第1版出版时间:2020-03内容提要:编辑推荐被优快云、InfoQ、极客时间等程序员技术社区频频转发的算法故事。青年意见领袖stormzhang、@码农翻身|刘欣、@Python爱好者社区|梁勇、@Hollis张洪亮、《Python3网络爬虫开发实战》作者崔庆才对《漫画算法》赞不...

weixin_40007515的博客 1645

小灰的《漫画算法》全面上架!

两周之前,小灰在公众号宣告了自己出书的消息,《漫画算法——小灰的算法之旅》开始预售。在短短的两周里,本书一度霸占着各大畅销榜榜首:(当当网计算机品类新书榜)在5月2日那一...

程序员小灰的博客 7621

[排序算法]堆排序

目录 一、堆排序过程 二、堆排序的代码实现 三、时间复杂度和空间复杂度 四、从宏观上看,堆排序和快速排序相比,有什么区别和联系呢

weixin_45922730的博客 523
上一篇: Java学习的正确打开方式
下一篇: 漫画:什么是优先队列?
废言Pro
博客等级 码龄16年 1092粉丝 142原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值