堆分为大根堆和小根堆,大根堆应用于升序排列,小根堆应用于降序排列。二叉堆借助数组实现,n个元素装在数组a[0]...a[n-1]中。堆排序是不稳定的排序。
利用大根堆的性质即其首元素是最大值。将首元素与a[n-1]互换,从a[0]到a[n-2]再重新调整为大根堆,此时a[n-1]有序;继续将首元素与a[n-2]互换,从a[0]到a[n-3]再重新调整为大根堆,此时a[n-2]a[n-1]有序;依次类推直至a[0]...a[n-1]有序,完成升序排列。降序排序利用小根堆原理相同。
以大根堆升序排序为例:
#include<iostream>
using namespace std;
void heapdown(int *a, int start, int end) //堆的向下调整为大根堆,范围是从start到end
{
int c = start;
int left = c * 2 + 1;
int tmp = a[c];
while (left <= end)
{
if (left < end&&a[left] < a[left + 1])
left++;
if (tmp >= a[left])
break;
else
{
a[c] = a[left];
c = left;
left = c * 2 + 1;
}
}
a[c] = tmp;
}
void heapsort(int *a, int n) //堆排序,首先将数组初始化为大根堆,然后交换首尾元素,重新调整大根堆,如此重复n-1次完成排序
{
for (int i = n / 2 - 1; i >= 0; i--)