堆排序
堆排序是一种特殊的选择排序。
大的原则还是如果升序 选择待排序类中最大排序码的元素放在最后位置 再选次大的放在倒数第二位置上 。。。。。最后把最小的放在第一个位置上。
堆排序是借助建堆和堆的向下调整算法进行选择的。
堆排序是一种效率很高的排序方法,尤其是在大量数据排序方面。
举例说明堆排序用法和逻辑:
将数组 int arr[] = {10,13,19,12,15,16,14,17,11,18}升序排序
先将数组建大堆:
大堆建好后 选出了待排序列中排序码最大的数作为堆顶。这时交换堆顶元素与待排序列最后一个元素,此时排序码最大的元素已经在最后的位置上。 这时对交换上去的堆顶元素使用向下调整算法把排序码次大的元素
调整到堆顶。再交换堆顶和待排序列倒数第二个元素。
循环直到排序码最小的元素到堆顶为止。
一次向下调整并交换堆顶与末尾元素的执行过程
代码实现:
template<class T, class Compare = Greater<int>>
void AdjustDown(T* arr, size_t N, int root)
{
int parent = root;
int child = parent * 2 + 1;
while (child < N){//这里的N 是传进来的end 此时向下调整的堆已经不包括堆中最后一个最大的数。
if (child + 1 < N && Compare()( arr[child + 1],arr[child]))
{
child++;
}
else if (Compare()(arr[child],arr[parent])){
swap(arr[child], arr[parent]);
parent = child;
child = parent * 2 + 1;
}
else{
break;
}
}
}
template<class T>
void HeapSort(T* arr, int N)
{
assert(arr);
for (int i = (N - 2) >> 1; i >= 0; --i)
{
AdjustDown(arr, N, i);//建堆
}
int end = N - 1;
while (end)//排序
{
swap(arr[0], arr[end]);
AdjustDown(arr, end, 0);/
/自堆顶开始向下调整。
--end;
}
}