#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
如果觉得我的文章对你有用,请随意赞赏