堆排序

堆排序是选择排序的一种, 所以, 下面的代码包含了最简单的选择排序.

#include <stdio.h>

typedef int ElementType;

// 交换元素
void Swap(ElementType *a, ElementType *b)
{
    ElementType t = *a;
    *a = *b;
    *b = t;
}

// 简单选择排序
void SimpleSelectionSort(ElementType A[], int N)
{
    int i, j, min;

    for(i = 0; i < N - 1; i++) // 寻找最小元素
    {
        min = i;
        for (j = i + 1; j < N; j++)
            if (A[j] < A[min])
                min = j; // min 记录最小元素位置
            // 将第 i 个元素与最小元素交换
            Swap(&A[i], &A[min]);
    }
}

// 将 N 个元素的数组中以 A[p] 为根的子堆调整为最大堆
// 注意, 这里的表示堆的数组中的数据是从 0 下标开始存放的, 所有子节点和父节点的关系这里要格外注意
void PercDown(ElementType A[], int p, int N)
{
    int Parent, Child;
    ElementType X;

    X = A[p]; // 取出根节点存放的值
    for (Parent = p; (Parent * 2 + 1) < N; Parent = Child)
    {
        Child = Parent * 2 + 1;
        if ((Child != N - 1) && (A[Child] < A[Child + 1]))
            Child++; // Child 指向左右子节点的较大者
        if (X >= A[Child]) // 找到了合适位置
            break;
        else // 下滤
            A[Parent] = A[Child];
    }
    A[Parent] = X;
}

// 堆排序
void HeapSort(ElementType A[], int N)
{
    int i;

    for (i = N / 2 - 1; i>= 0; i--) // 建立最大堆
        PercDown(A, i, N);

    for (i = N - 1; i > 0; i--) // 删除最大堆顶
    {
        Swap(&A[0], &A[i]);
        PercDown(A, 0, i); // 将 i 个元素的数组中以 A[0] 为根的子堆调整为最大堆
    }
}

int main() {
    ElementType A[8] = {99,66,45,33,37,10,22,13};

    HeapSort(A, 8);

    for(int i = 0; i < 8; i++)
        printf("%d ", A[i]);

    return 0;
}

测试结果:

20201127002333

原文地址:https://www.cnblogs.com/fanlumaster/p/14045574.html