算法技术手册 - 排序 - 堆排序

堆排序依赖于上午写道的构建堆和调整堆。

基本思想:
(1)首先执行BuildHeap(以最大堆为例),则arr[0]已经是最大元素了,如果我们要按照从小到大排序,那么它应该被放在arr[n-1]上,于是,我们swap arr[0]和arr[n-1]。
(2)类似的,我们让i从n-1到0,依次执行调整堆,AdjustHeap(i,n),每次调整完成后,堆顶部一定是最大元素,正好把他换到i-2上。
上述的思路和选择排序是不是非常相似!

改进:
调整堆实际用到了递归方法,而其实它是可以非递归化的。非递归化后,性能较递归版本有略微的提升。

全部代码如下:

#include <stdio.h>

typedef long TYPE;

void swap(TYPE* a, TYPE* b)
{
    TYPE tmp;
    tmp = *a;
    *a = *b;
    *b = tmp;
}

//adjust heap()
void heapify(TYPE* heap, int idx, int n)
{
    //left and right index
    int left = 2 * idx + 1;
    int right = 2 * idx + 2;
    int large = 0;

    //Check left
    if(left<n && heap[left]>heap[idx])
    {
        large = left;
    }
    else
    {
        large = idx;
    }

    //Check right
    if(right<n && heap[right]>heap[large])
    {
        large = right;
    }

    //Swap idx and max one
    if(idx!=large)
    {
        swap(&heap[idx], &heap[large]);
        heapify(heap, large, n);
    }
}

void buildHeap(TYPE* heap, int n)
{
    int i=n/2-1;
    for(; i>=0; i--)
    {
        heapify(heap, i, n);
    }
}

void heapSort(TYPE*heap, int n)
{
    int i;
    buildHeap(heap, n);
    for(i=n-1; i>=1; i--)
    {
        swap(&heap[0], &heap[i]);
        heapify(heap, 0, i);
    }
}

int main()
{
    TYPE arr[16] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};
    int i;
    int len;

    len = sizeof(arr)/sizeof(TYPE);

    //Test heapify
    //heapify(arr, (len-1)/2, len);
    //buildHeap(arr, len);
    heapSort(arr, len);

    //print
    for(i=0; i<len; i++)
    {
        printf("%ld ", arr[i]);
    }
    printf("\n");

}

Leave a Reply

Your email address will not be published. Required fields are marked *