堆排序

原理

将数组构建成大顶堆,然后将根节点与堆底元素交换,最大值排到了末尾,再将剩下的n-1个元素再构成大顶堆,重复操作。

堆是具有以下性质的完全二叉树:每个结点的值都大于或等于其左右孩子结点的值,称为大顶堆;或者每个结点的值都小于或等于其左右孩子结点的值,称为小顶堆。如下图:

完全二叉树

假设一个二叉树有n层,那么如果第1到n-1层的每个节点都达到最大的个数:2,且第n层的排列是从左往右依次排开的,那么就称其为完全二叉树

分析

最好、最坏,平均都为o(nlogn)

大顶堆:arr[i] >= arr[2i+1] && arr[i] >= arr[2i+2]  

小顶堆:arr[i] <= arr[2i+1] && arr[i] <= arr[2i+2]  

代码

void heap_build(int &arr[],int root,int len){
    int left = 2*root +1;
    int right = left +1;
    int max = root;
    if(left<len && arr[left]>arr[max]) max=left;
    if(right<len && arr[right]>arr[max]) max=right;
    if(max != root){
        swap(arr[root],arr[max]);
        heap_build(a,max,size);//此时max位置就是原来root的位置,他已经管不了他的孩子了,所以要从他开始构建堆,找到能管两个孩子的节点
    }
}
//刚开始先从下往上建立堆,然后从上往下调整堆,因为堆顶拿走了,如果从下往上调整,就没变化
void heap_sort(int &arr[],int len){
    for(int i=len/2-1;i>=o;i--) heap_build(arr,i,len);
    for(int j=len-1;j>=0;j--){
        swap(arr[0],arr[j]);
        heap_build(arr,0,j);
    }
}
原文地址:https://www.cnblogs.com/pacino12134/p/11326723.html