#include<stdio.h>
void heap_adjust(int arr[], int father, int n)
{
// 调整为大顶堆
int child = father * 2 +1; // 左子节点
int tmp = arr[father];
while(child < n)
{
// 如果该节点有两个子节点,则取其中较大的一个,否则取左子节点
if(child+1 < n && arr[child] < arr[child+1]) child++;
if(arr[father] >= arr[child]) break;
// 如果较大的子节点小于该节点,则不需要继续调整,退出
arr[father] = arr[child];
father = child;
child = father * 2 + 1;
arr[father] = tmp;
}
}
void build_heap(int arr[], int n)
{
// 建堆时从非叶子结点开始调整
for(int i = (n-1)/2; i >= 0; --i)
{
heap_adjust(arr, i, n);
}
}
void heap_sort(int arr[], int beg, int end)
{
// 堆排序,先建堆
// 然后每一次交换未调整好的最后一个元素和第一个元素
build_heap(arr+beg, end-beg);
for(int tmp, i = end-1; i > beg; --i)
{
tmp = arr[i]; arr[i] = arr[0]; arr[0] = tmp;
heap_adjust(arr+beg, 0, i);
}
}
int main()
{
int arr[100];
int n;
scanf("%d", &n);
for(int i = 0; i < n; i++) scanf("%d", &arr[i]);
heap_sort(arr, 0, n);
for(int i = 0; i < n; i++) printf("%d ", arr[i]);
return 0;
}
Last modification:July 26, 2020
© Allow specification reprint