最近在做个堆排序的时候有点疑惑,疑惑在于对一个乱序数组利用堆排序使之有序。
先了解两个概念:小顶堆(根结点的值小于子结点的值)和大顶堆(根结点的值大于子结点的值)。
n个元素的序列{k1,k2,…,kn}当且仅当满足下列关系之一时,称之为堆。
情形1:ki <= k2i 且ki <= k2i+1 (最小化堆或小顶堆)
情形2:ki >= k2i 且ki >= k2i+1 (最大化堆或大顶堆)
其中i=1,2,…,n/2向下取整;
一开始的时候,或者说是潜意识下认为,如果想要使一个乱序数组利用堆排序使之升序(数组从小到大),就要建立小顶堆;而要使数组变成降序(数组从大到小),就要建立大顶堆。
先给个结论:这个思路完全错误。实质上的结论是:想要使一个乱序数组利用堆排序变成升序数组,需要建立大顶堆;要使一个乱序数组利用堆排序变成降序数组,需要建立小顶堆。
我们需要注意,把乱序数组变成升序数组的时候,是把建立好的堆的堆顶和堆尾元素交换,是把交换后的结点值进行排序。所以当给乱序数组建堆的时候,只有建立最大堆使堆顶元素为整个堆的最大值,然后把堆顶与堆尾交换,堆尾就变成最大值。然后继续第二轮的建立最大堆,得到的堆顶和倒数第二个堆尾交换……依次建立最大堆,交换……最终得到了一个升序的堆,即达到升序。
参考: