6在我的堆排序预备篇中,我已经给大家介绍了如何建立一个大根堆。那么在这一篇文章中我将给大家介绍堆排序。堆排序是时间复杂度为 O(N*LogN),额外空间复杂度为O(1)的一个算法。
堆排序的步骤:
1.先形成大根堆
2.将下标为最后的位置与下标为0(根节点)交换。
3.将交换后的堆大小减一,减一后的堆继续使它形成一个大根堆。
4.重复进行2,3操作,直到堆的大小减为1。
接下来我给大家分析一下上述步骤。
1.为什么形成大根堆并没有排好序呢?大家看看这种情况。
并不是有序的。
2.为什么是将根节点与最后一个交换?
因为这个堆是大根堆,根节点的值肯定是这个数组的最大值。将它与最后一个位置交换然后堆减一(数组长度减一)就意味着最大的数肯定在数组最后。
然后只需将[0,arr.length-2]区间继续形成一个大根堆,我们称之为heapify的过程。
接着重复2,3操作。继续将[0,arr.length-2]区间根节点和最后一个换位置。也就是5和3换。
是不是5又来到了正确位置呢?一直循环。这样就排好序了。这就是堆排序的过程。
接下来来看一下代码。
我们来分析一下代码。
首先我们需要建立大根堆。heapInsert就是建立大根堆。将数组的每一个元素都放到大根堆。接着根节点与最后一个节点交换位置。然后进行重建大根堆,我们称之为heapify过程。接着重复这个过程直到size为1。
大根堆的建立过程我就不多讲了。在我的上一篇文章堆排序预备篇就给大家说得很清楚了。
重新建立大根堆。首先index的左右两个孩子先PK一下找出左右孩子中较大的一个。这里就是largest。然后在和index比较,如果当前节点比左右孩子较大的一个还大。那么就不必调整。直接break结束循环。否则就把当前节点和较大节点交换。index来到左右孩子较大的那个位置。继续执行循环。
接着我们运行以下程序吧。
接着我们运行一下程序吧。
排序成功。堆的结构很重要哦。以后要说的贪心算法其实就是利用了堆的结构。还有优先队列等等。这里堆排序就给大家介绍完了。