堆排序算法的步骤:
例如大顶堆
1、首先将要排序的数组构造成一个大顶堆,数组本身可以看作是一个完全二叉树的顺序存储结构,构建大顶堆是一个从下至上进行筛选的过程,从最后一个非终端结点(N/2)开始(当数组元素是从下标1开始存储的,最后一个非终端结点的下标就是N/2)。如果发现左右子结点的值大于父结点,则将两者互换,对每一个非终端结点筛选完成后就形成了一个大顶堆。
2、取出堆首元素(此时为最大的元素),将堆首元素与大顶堆的最后一个元素互换,此时最大的元素来到了数组的末尾。然后再将除末尾元素的(N-1)个元素构造成大顶堆。因为只有堆首元素发生了改变,所以在重新构造大顶堆的时候只需要筛选堆首元素即可。
大顶堆排序的代码如下:
//大顶堆排序
#include<iostream>
#include<vector>
using namespace std;
#define _CRT_SECURE_NO_WARNINGS 1
void HeapAdjust(vector<int>&a, int s, int m) // 对结点进行调整
{
//判断其子节点是否大于父结点
int re = a[s];
for (int i = 2 * s; i <= m; i = i * 2)
{
if (i < m && a[i + 1] > a[i])// 右孩子比左孩子大,则父结点与右孩子比较
{
i++;
}
if (re >= a[i])
{
break;
}
else
{
a[s] = a[i];
s = i;
}
}
a[s] = re;
}
void Heapsort(vector<int>&a, int n)
{
for (int i = n / 2; i > 0; i--) // 步骤一:将数组构造成大顶堆
{
HeapAdjust(a, i, n);
}
int temp;
for (int j = n; j > 0; j--) // 步骤二、将堆首元素与数组尾元素进行交换,再将n-1个元素构造成大顶堆
{
temp = a[1];
a[1] = a[j];
a[j] = temp;
HeapAdjust(a, 1, j - 1);
}
}
int main()
{
int n = 0;
int i;
scanf("%d", &n); // 输入待排序的数据的个数
vector<int> a(n+1, 0);
for (i = 1; i < n + 1; i++) // 数组元素是从下标1开始的
{
scanf_s("%d", &a[i]);
}
Heapsort(a, n);
return 0;
}