一、定义

借助堆结构实现的排序算法被称为堆排序。

二、过程说明

1、建堆

(1)方法1

原地建堆,对于数组来说,从前往后;对于树来说,从下向上。

将数组的第一个元素作为堆顶,第二个元素做向堆中插入数据的操作,即:从下向上堆化。直至所有的元素均完成所有插入操作,此时堆就建立完成了。

(2)方法2

原地建堆,对于数组来说,从后往前;对于树来说,从上向下。

从数组倒数第一个非叶子节点向下进行堆化,之后是倒数第二个非叶子节点向下堆化,直至堆化到数组第一个节点,从而完成堆的建立。

(3)方法 2 和方法 1 的区别

方法 2 默认数组开始时已经是一颗树了,但是不是堆结构。之后的操作就是不断比较交换,使得该树满足堆结构。

方法 1 则从 0  开始建堆,当树建好时,就是一颗标准的堆了。

(4)时间复杂度

这里说下方法 2 的时间复杂度。实际上真正进行堆化的节点为非叶子节点,并且是从上到下进行堆化。每个节点堆化的时间复杂度实际上是该节点的高度,总结如下图所示:

数据结构与算法 / 排序算法 / 堆排序

经过下图推算,得出时间复杂度为 O(n) 。

数据结构与算法 / 排序算法 / 堆排序

 

2、排序

堆建完之后排序就很简单了,因为此时的堆顶已经是最大值(最小值)了,取出该值放到叶子节点的位置,原本叶子节点位置的数值移动到堆顶点,在进行一次从上到下的堆化,重新得到堆顶是第 2 大(小)的数。经过多次堆化,就能得到从大到小或者从小到大的数据了。

排序阶段的时间复杂度为 O(nlogn),因为每次堆化时都是将叶子节点放到顶点然后从上到下堆化,堆化一次就相当于比较 logn 次,logn 为树的高度,需要比较 n 次,所以时间复杂度为 O(nlogn) 。

由于建堆 + 排序的时间复杂度为 O(n) + O(nlogn),省略之后时间复杂度为 O(nlogn) 。

三、总结

由于堆排序的过程中,需要轮着将数据放到堆顶点进行堆化,导致该排序不是稳定性排序。

同时由于整个过程只需要在本数组内就能完成整个过程,需要其他内存很少,故堆排序时原地排序。 

算法种类 时间复杂度 空间复杂度 原地排序 稳定性排序
堆排序 O(nlogn) O(n) ×

 

参考:极客时间《数据结构与算法之美》王争

这门课真心推荐,内容很经典、栗子很形象,里面还包含了很多面试题目。真是居家旅行必备良药。

 

(SAW:Game Over!)

相关文章:

  • 2022-12-23
  • 2021-12-23
  • 2021-05-31
  • 2021-05-01
  • 2022-03-03
  • 2022-12-23
  • 2021-07-05
  • 2022-12-23
猜你喜欢
  • 2022-12-23
  • 2021-10-04
  • 2022-12-23
  • 2021-06-06
  • 2022-02-08
  • 2022-12-23
  • 2021-08-09
相关资源
相似解决方案