堆排序(heapsort)

样例:A[10]={4,1,3,2,16,9,10,14,8,7}

伪代码(用的是最大堆):

维护堆性质:
MAX_HEAPIFY(A,i)
l=LEFT(i)                //LEFT(i)是i的函数这里LEFT(i)=2i+1
r=RIGHT(i)            // RIGHT (i)是i的函数这里RIGHT (i)=2i+2
if l<=A.heap_size and A[l]>A[i]
    largest=l;
else
    largest=i
if r<=A.heap_size and A[r]>A[largest]
    largest=r;
if largest !=i
    exchange A[i] with A[largest]
    MAX_HEAPIFY(A,largest)
建堆:
BUILD_MAX_HEAP(A)
A.heap_size=A.length
for i=A.length/2 downto 1
    MAX_HEAPIFY(A,i)
堆排序:
HEAPSORT(A)
    BUILD_MAX_HEAP(A)
    for i=A.length downto 1            //书上是2,书上应该错了
        exchange A[1] with A[i]
A.heap_size=A.heap_size-1
        MAX_HEAPIFY(A,1)

C语言代码:

#include<stdio.h>
void MAX_HEAPIFY(int* A, int i);
void BUILD_MAX_HEAP(int* A);
void HEAPSORT(int* A);
void swap(int* i, int* j);
int A_length = 10;
int A_heapsize = 10;
int main() 
{
    int A[10] = { 4, 1, 3, 2, 16, 9, 10, 14, 8, 7 };
    int i;
    HEAPSORT(A);
    for (i = 0; i < A_length; i++)
        printf("%d\t", A[i]);
    printf("\nhello..");
    system("pause");
    return 0;
}
void MAX_HEAPIFY(int* A, int i)        //维护堆性质
{
    int l = 2 * i + 1;
    int r = 2 * i + 2;
    int largest;
    if (l<A_heapsize && A[l]>A[i])
        largest = l;
    else
        largest = i;
    if (r < A_heapsize && A[r]>A[largest])
        largest = r;
    if (largest != i)
    {
//        printf("%d和%d交换\n", A[i], A[largest]);
        swap(&A[i], &A[largest]);
        MAX_HEAPIFY(A, largest);
    }
}
void BUILD_MAX_HEAP(int* A)        //建堆
{
    int i;
    for (i = (A_length-1) / 2; i >= 0; i--)
    {
        MAX_HEAPIFY(A, i);
//        printf("i=%d\n", i);
    }
}
void HEAPSORT(int* A)        //堆排序
{
    BUILD_MAX_HEAP(A);
    int i;
//    printf("第一次建堆完成\n");
//    for (i = 0; i < A_length; i++)
//            printf("%d\t", A[i]);
    for (i = A_length-1; i > 0; i--)
    {
        swap(&A[0], &A[i]);    
        //printf("%d\n", A[i]);
        A_heapsize = A_heapsize - 1;
        MAX_HEAPIFY(A, 0);
        
    }
}
void swap(int* i, int* j)
{
    int t;
    t = *i;
    *i = *j;
    *j = t;
}

递归调用难点,注意边界条件!!!

posted @ 2018-03-16 09:11  Alexadar  阅读(214)  评论(0)    收藏  举报