heap-sort-源码-堆排序

来源:互联网 发布:iphone屏幕检测软件 编辑:程序博客网 时间:2024/05/29 15:12
#include <stdio.h>
#include <stdlib.h>

static void
swap(int *l, int *r)
{
    int temp = *l;
    *l = *r;
    *r = temp;
}

// 调整堆, 供建立堆及堆排序使用
// 从i节点开始调整堆
// 自上向下的调整
// 参数: 1数组,2数组大小,3当前节点!
static void
AdjustHeap(int a[], int i, int size)
{
    int lc = 2*i+1;
    int rc = lc+1;
    int max = i;

    if (lc < size && a[lc] > a[max])
        max = lc;
    if (rc < size && a[rc] > a[max])
        max = rc;

    // 如果父节点不是最大节点
    // 1 交换节点
    // 2 调整子树
    if (max != i) {
        swap(a+max, a+i);
        AdjustHeap(a, max, size);
    }
}

// 构造堆
// 针对所有的非叶子节点, 从后向前调整堆
// 建造堆就是从最下层的最后一个非叶子节点开始向前向上调整堆的操作
// 参数:1数组,2数组大小
static void
BuildHeap(int a[], int size)
{
    int i = size%2 ? (size-1)/2 : (size-2)/2;
    while(i >= 0) {
        AdjustHeap(a, i, size);
        i--;
    }
}

//HeapSort,
// 1. 建造堆(BuildHeap)
// 2.1 交换顶点到最后的有序区
// 2.2 重新从最高顶点处(因为最高顶点刚刚被换到后面的有序区,堆的特性被破坏了)调整堆
void
HeapSort(int a[], int size)
{
    int k;

    BuildHeap(a, size);

    // 堆排序前n项为非有序的,而n后项为有序项。
    // 与选择排序相反
    k = size;
    while (--k > 0)    {
        swap(a, a+k);
        AdjustHeap(a, 0, k);
    }
}

int
main()
{
    int a[]={0,16,20,3,11,17,8};
    int size = sizeof(a) /sizeof(int);
    int i;

    HeapSort(a, size);

    i = -1;
    while (++i < size)
        printf("%d    ", a[i]);

    getchar();

    return 0;
}