堆排序

作者: 金戈大王 | 来源:发表于2017-01-13 18:41 被阅读90次

阅读经典——《算法导论》05

本文介绍一种神奇的排序方法:堆排序。

堆排序不像插入排序和归并排序那样直观,它利用了一种称为堆的数据结构。

是一个数组,它可以被看成一个近似的完全二叉树,树上的每一个结点对应数组中的一个元素。除了最底层外,该树是完全充满的,而且是从左向右填充。

下图分别为以二叉树和数组形式展现的一个最大堆。

最大堆

最大堆中的每一个结点都比它的两个孩子结点大(如果孩子结点存在的话)。显然,整个二叉树的根结点是堆中所有元素的最大值。类似地,最小堆的每一个结点都比它的两个孩子结点小。无论是最大堆还是最小堆,它们的工作原理都是一样的,因此本文以最大堆为例,因为使用最大堆排序得到的恰好是递增序列。

堆具有两个重要操作:建堆和维护堆。

建堆是将一个无序的数组建立成满足堆性质的数组,即上图(b)所示的数组。

建堆的过程如下图所示:

建堆

先将无序数组按从上到下、从左到右的顺序建立二叉树,如图(a)。然后从后向前找到第一个不是叶子结点的结点,对该结点执行维护堆操作,完成后该结点对应的子树就满足了堆的性质。继续向前遍历所有的结点,重复维护堆操作,直到根结点对应的堆(即完整的堆)满足堆的性质。

维护堆是对于这种情况:当结点i的左子树和右子树都是堆,但加上i后不满足堆的性质时,需要做的操作。

维护堆的过程如下图所示:

维护堆

若要维护结点 i,则将结点i与它的两个孩子结点比较。若 i 比它们大,那么 i 子树已经满足的最大堆的性质,不需要做任何操作。若 i 比它们小,那么需要找出其中最大的一个孩子,将 i 与它交换,交换后,这三个元素就满足了最大堆的性质,但 i 还要继续与现在的两个孩子比较,因为 i 仍然有可能破坏了当前位置的最大堆性质。如此下去,直到 i 的两个孩子都比它小,维护堆的过程宣告结束。

堆排序

现在我们可以考虑如何使用堆实现一个排序算法。由于最大堆的根结点保存了数组的最大值,因此可以每次将根结点的值从数组中取出,再令剩下的元素重新形成堆,如此往复,就可以依次从大到小取出数组中的所有元素。

下图所示为堆排序的完整流程。

堆排序

图(a)为建堆后的结果。从(a)到(b)的具体过程为:取出根结点16放到末尾,然后把最后一个叶子结点1放到根结点的位置(注意此时堆的元素少了一个),执行一次“维护堆”操作,结果就成了图(b)所示的样子。不断重复这个过程,直到所有结点都离开了堆,堆排序算法就结束了。结果是一个从小到大的数组。

堆排序是原址排序,不需要额外的内存空间,因为堆中元素只存在交换位置的操作,数组在原有地址里排序。

性能分析

考虑堆排序的时间复杂度。最开始的建堆操作时间复杂度不太容易看出来,但可以证明这个操作的时间复杂度是O(n),愿意深究的朋友请参考《算法导论》6.3节。排序过程中,需要取出n个数,每取出一个数就要执行一次“维护堆”操作,每次维护堆操作的时间与堆的高度(即lgn)成正比,因此排序过程时间复杂度为O(nlgn)。总时间复杂度也是O(nlgn)。

堆排序与之后将要介绍的快速排序相比,优点在于最坏情况时间复杂度也是O(nlgn),而快速排序则是Θ(n2)。

实现代码

为了缩减篇幅,具体代码就不在文中讲解了。完整代码见HeapSort.java

关注作者文集《算法导论》,第一时间获取最新发布文章。

获取文集中的全套源码请访问GitHub代码仓库Algorithm

相关文章

  • 堆排序

    目录 1.堆排序介绍 2.堆排序图文说明 3.堆排序的时间复杂度和稳定性 4.堆排序实现 堆排序介绍 堆排序(He...

  • 堆排序---基础篇

    本文主要介绍堆排序的一些基本过程和分析。 大纲 堆排序简介 堆排序代码实现 1. 堆排序简介 1.1 堆排序的存储...

  • 堆和堆排序

    最小K个数 堆排序 堆排序

  • JS实现堆排序

    原理 堆排序原理 实现 说明 堆排序对大文件很有效 堆排序是不稳定排序

  • iOS算法总结-堆排序

    iOS算法总结-堆排序 iOS算法总结-堆排序

  • 堆排序

    转载:图解排序算法(三)之堆排序 预备知识 堆排序 堆排序是利用堆这种数据结构而设计的一种排序算法,堆排序是一种选...

  • 排序

    原创 堆排序: 使用visit数组从本质出发获取大顶堆排序。

  • 堆排序

    堆排序

  • C++基础入门之模板堆排序(上):模板上的list的创造与操作

    整段源码链接C++的模板元堆排序 要点 组建数据结构list 组建对list的各种基本操作 堆排序中组建堆排序个个...

  • 3.2-选择排序-堆排序

    参考链接 选择排序:堆排序(Heap Sort) 白话经典算法系列之七 堆与堆排序 堆排序与快速排序,归并排序一样...

网友评论

    本文标题:堆排序

    本文链接:https://www.haomeiwen.com/subject/vyysbttx.html