堆排序,就像它的名字一样,利用了堆的特性来进行排序。实现堆排序的思路是,把数组构建成一棵二叉树,并随着每次堆的变化更新堆顶的最大/最小值。堆排序的时间复杂度在所有情况下都是 O(nlgn),它也是一个不稳定的算法。在开始编写堆排序的程序之前,我们首先要了解“堆”的概念。
堆是一种数据结构,它是一种特殊的完全二叉树:如果这个堆是一个大顶堆(最大的元素在堆顶),那么每个节点上的元素都应该比它的子节点上的元素要大,最大的元素在根节点上;反之,如果是小顶堆,那么每个节点上的元素都应该比它的子节点小,最小的元素在根节点上。
图 1 所示为大顶堆,位于根节点上的 59 是整个堆中最大的数。在堆排序中,我们需要把堆用一个数组的形式表示。

图 1:大顶堆
如图 2 所示,为堆的每一个节点编号。从根节点开始,把完全二叉树的每一层从左到右依次编号。图 2 就是前面的堆编好号的结果。随后,以编号为下标,把堆里的每一个元素放到一个数组里。

图 2:节点编号
图 3 就是堆里的元素存放在数组中的样子。

图 3:二叉树的数组表示方式
因为数组的下标从 0 开始,而堆的编号从 1 开始,所以数组的第一个位置留空。为什么可以这样存放元素呢?观察堆的编号,我们发现每个非叶子节点的左子节点,其编号都为父节点的两倍;每个非叶子节点的右子节点,其编号都为父节点的两倍加一。
所以,在数组中,我们可以对元素的下标进行相似的操作,从而找到每个节点

本文介绍了堆排序算法的工作原理,详细阐述了如何构建大顶堆,并通过一系列步骤展示了如何进行堆排序。堆排序的时间复杂度为O(nlgn),且不稳定性。文章通过实例解释了如何从大顶堆开始,通过交换堆顶元素与末尾元素并重新调整堆,最终完成排序过程。
最低0.47元/天 解锁文章

被折叠的 条评论
为什么被折叠?



