堆排序

 堆是是具有以下性质的完全二叉树:每个结点都大于或等于它的左右结点(大顶堆),或者每个结点都小于或等于它的左右结点(小顶堆),左右结点之间没有要求。

该算法的主要思想是:

1.假设现在已有一个大顶堆(调用buildheap()函数完成创建)。

2那么它的根结点肯定是最大的,现在将根结点与最后一个结点交换位置,使得最大值放到了最后,较小值放在了最前,放到最后表示这个数已排序完成,只需要排序它前面的数,即将数组长度减一。

3.因为最前有个较小数,所以需要重新用剩下的数组构成一个大顶堆(同样是调用buildheap())。

4.重复2,3步骤,直到数组中所有数字排序完成。

buildheap()函数:

传入一个结点,然后与它左右子树中最大的子树比较,若它大,满足堆性质,退出函数,若子树大,将子树放到它的位置,它的位置移动到子树位置,继续比较,直到子树比它小,退出函数。

 

 

#include"iostream"
#include"time.h"
using namespace std;
void show(int *a,int n){
    for(int i = 0;i < n;i++){
        cout<<a[i]<<ends;
    }
    cout<<endl;
}
void buildheap(int *a,int s,int n){
    int temp = a[s];
    for(int i = 2 * s + 1;i < n;i = i * 2 + 1){
        if(i < n - 1 && a[i] < a[i + 1]){
            i++;
        }
        if(temp < a[i]){
            a[s] = a[i];
            s = i;
        }
        else{
            break;
        }
    }
    a[s] = temp;
}
//堆排序
void heapsort(int *a,int n){
    for(int i = n / 2;i >= 0;i--){
        buildheap(a,i,n);
    }
    for(i = n - 1;i >= 0;i--){
        int temp = a[i];
        a[i] = a[0];
        a[0] = temp;
        buildheap(a,0,i);
    }
}
int main(){
    const int N = 10;
    int a[N];
    srand(time(NULL));
    for(int i = 0;i < N;i++){
        a[i] = rand() % 10;
    }
    show(a,N);
    heapsort(a,N);
    show(a,N);
    return 0;
}

 

posted @ 2018-05-24 00:09  oleolema  阅读(226)  评论(0编辑  收藏  举报