算法学习 - 堆排序 ( HeapSort ) C++实现

HeapSort

堆排序的原理比较简单,首先明白优先队列的二叉堆,还有它的插入和删除操作就可以了,不懂的话,请看我之前的一篇文章:优先队列的二叉堆实现

排序操作分两步:

第一步构造堆

这个不能和优先队列的插入操作一样,虽然看起来时间复杂度差不多,每次都进行插入操作是O(1)和O(logN)之间,所以总运行时间是平均复杂度是O(N)而不是O(NlogN)最坏时间复杂度,我们的做法是先把数列构造成一棵树,然后依次下滤。时间复杂度也是O(N),最多用到2N次比较。

第二部删除堆顶元素

一共要删除N次,每次删除进行2logi次比较,因为堆顶元素一直是最大值,或者是最小值(小顶堆)。把删掉的元素找个地方存起来~ 这样子就是有序的数列了。放到哪里呢= =。一种是开个O(N)的空间,舍弃这种方法。一种是把删掉的元素放到 数列尾部啊,因为删掉一个元素,原数列尾部就空出一个位置了,这样子不断存放,就是有序的了。至于大顶堆还是小顶堆看你要从大到小还是从小到大了。

代码实现

//
//  main.cpp
//  heapSort
//
//  Created by Alps on 14-8-2.
//  Copyright (c) 2014年 chen. All rights reserved.
//

#include <iostream>
#define ElementType int
#define MinItem -1
using namespace std;




void Swap(int &a, int &b){
    a = a+b;
    b = a-b;
    a = a-b;
}

void BuildHeap(ElementType *A, int length){
    for (int i = length/2; i > 0; i--) {
        for (int j = i; j*2 <= length;) {
            if (j *2 != length) {
                if (A[j*2] > A[j*2+1] && A[j*2] > A[j]) {
                    Swap(A[j*2], A[j]);
                    j *= 2;
                }else{
                    if (A[j*2+1] > A[j*2] && A[j*2+1] > A[j]) {
                        Swap(A[j*2+1], A[j]);
                        j = j*2+1;
                    }else{
                        break;
                    }
                }
                
                
            }else{
                if (A[j*2] > A[j]) {
                    Swap(A[j*2], A[j]);
                    j *= 2;
                }else{
                    break;
                }
            }
        }
        
    }
}

ElementType DeleteMax(ElementType *A, int length){
    int MaxElement, LastElement;
    int i,temp;
    MaxElement = A[1];
    LastElement = A[length];
    for (i = 1; i*2 < length; i = temp) {
        temp = i*2;
        if (A[temp] > A[temp+1]) {
            A[i] = A[temp];
        }else{
            A[i] = A[temp+1];
            temp++;
        }
        if (LastElement > A[i]) {
            A[i] = LastElement;
            break;
        }
    }
    A[i] = LastElement;
    return MaxElement;
}

void HeapSort(ElementType *A, int length){
    BuildHeap(A, length);
    for (int i = 0; i < length; i++) {
        A[length-i] = DeleteMax(A, length-i);
    }
}


int main(int argc, const char * argv[])
{

    ElementType A[]={MinItem,53,26,41,59,97,31,58};
    int length = sizeof(A)/sizeof(ElementType) -1;
    HeapSort(A, length);
//    BuildHeap(A, length);
    for (int i = 1; i <= length; i++) {
        printf("%d ",A[i]);
    }
    printf("\n");
//    for (int i = 0; i < length; i++) {
//        A[length-i] = DeleteMax(A, length-i);
//        printf("%d ",A[length-i]);
//    }
    printf("\n");
    return 0;
}
    原文作者:排序算法
    原文地址: https://blog.csdn.net/alps1992/article/details/38702749
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞