堆排序从小到大排序:首先将数组元素建成大小为n的大顶堆,堆顶(数组第一个元素)是所有元素中的最大值,将堆顶元素和数组最后一个元素进行交换,再将除了最后一个数的n-1个元素建立成大顶堆,再将最大元素和数组倒数第二个元素进行交换,重复直至堆大小减为1。
动图描述:
#include <iostream>
using namespace std;
// 大根堆排序
void HeapAdjust(int array[], int s, int n);
void swap(int array[], int i, int j);
void heapSort(int array[], int n)
{
// 生成大根堆
for (int i = n / 2; i > 0; i--)
{
HeapAdjust(array, i, n);//从下向上,从右向左调整(从中间节点,总数/2 的下标节点处开始,往下标为1节点调整)
}
for (int i = n; i > 1; i--)
{
swap(array, 1, i);// 交换,形成非大根堆
HeapAdjust(array, 1, i - 1);//从上到下,从左向右调整
}
}
// 每次调用盖函数会形成一个大根堆,每个父节点都比其左右子节点打
void HeapAdjust(int array[], int s, int n)
{
int i, temp;
temp = array[s];// 保存当前父节点的值
for (i = 2 * s; i <= n; i *= 2)// for循环将较小的父节点往更底层交换
{
// 这条if语句是找出s节点下,左右较小的那个节点i
if (i < n && array[i] < array[i + 1])//i,i + 1为节点位置s节点的子节点 i<n判断是否超出节点数量
{
i++;// 较大的子节点
}
if (temp >= array[i])// 父节点与较大子节点的比较
{
break;// 父节点较大则停止交换
}
array[s] = array[i];// 子节点顶替父节点位置
s = i;// 记录下父节点 要换到的子节点位置
}
array[s] = temp;// 将该子节点置为父节点的值
}
// 交换当前未调整堆的头尾节点
void swap(int array[], int i, int j)
{
int temp;
temp = array[i];
array[i] = array[j];
array[j] = temp;
}
int main()
{
// 注意:数组从1开始,1~n
int array[] = { 0, 1, 8, 6, 3, 2, 5, 4, 9, 7 };// 第一个位置不用
int array1[] = { 0, 1, 8, 6, 3, 2, 0, 5, 4, 9, 7 };// 第一个位置不用
heapSort(array,9);
heapSort(array1, 10);
getchar();
}