堆排序

堆排序算法主要过程是保持堆的性质:max_heapify()。它的作用是:

对一个大顶堆,如果拿掉堆顶元素,换成另一个元素,如果这个元素比堆顶的左右儿子小,那么就不满足大顶堆的性质,这时,max_heapify()通过逐步向下进行更新,可以达到维护大顶堆的效果,具体是将新的堆顶元素与左右儿子比较,如果比左右儿子都大说明不用更新就是一个大顶堆了;如果比左儿子小,将这个值与左儿子互换,然后对左子树递归进行同样的操作,最后形成一个大顶堆。

堆排序的过程是,首先对所给元素建一个大顶堆,那么这些元素中的最大值显然就是堆顶元素了,然后,把这个元素放到序列(数组)的最后,对除了它之外的元素进行一次max_heapify,找出剩余元素中的最大值,放到倒数第二位置,以此类推,最后得到升序序列。

View Code
# include <stdio.h>

# define lson(i) ( (i) << 1 )
# define rson(i) ( ((i) << 1) + 1)


/*******************************************************************/
void swap(int * x, int * y)
{
    int tmp;

    tmp = *x;
    *x = *y;
    *y = tmp;
}

void max_heapify(int * A, int i, int heapsize)
{
    int l, r, largest;

    l = lson(i);
    r = rson(i);

    if ( l<=heapsize && A[l]>A[i] )
    {
        largest = l;
    }
    else
    {
        largest = i;
    }
    if ( r<=heapsize && A[r]>A[largest] )
    {
        largest = r;
    }

    if ( largest != i )
    {
        swap(&A[i], &A[largest]);
        max_heapify(A, largest, heapsize);
    }
}

void build_max_heap(int * A, int n)
{
    int i;

    for (i = n/2; i >= 1; --i)
    {
        max_heapify(A, i, n);
    }
}

void heap_sort(int * A, int n)
{
    int heapsize, i;

    heapsize = n;
    build_max_heap(A, n);
    for (i = n; i >= 2; --i)
    {
        swap(&A[i], &A[1]);
        --heapsize;
        max_heapify(A, 1, heapsize);
    }
}

/*******************************************************************/

void init(int * A, int n)
{
    int i;

    A[0] = n;
    for (i = 1; i <= n; ++i)
    {
        scanf("%d", &A[i]);
    }
}

void solve(int * A, int n)
{
    heap_sort(A, n);
}

/*******************************************************************/
int main()
{
    int A[100005];
    int n, i;

    freopen("heap_sort.txt", "r", stdin);

    while (~scanf("%d", &n))
    {
        init(A, n);
        solve(A, n);
        for (i = 1; i <= n; ++i)
        {
            printf("%d", A[i]);
            printf(i<n ? " ":"\n");
        }
    }

    return 0;
}
原文地址:https://www.cnblogs.com/JMDWQ/p/2857669.html