堆排序(实现c++)

  堆可以看作是一个完全二叉树,分为大顶堆和小顶堆,本文我们以大顶堆为例来实现堆排序。

  (1)建堆

  先把给定的序列转换成一棵完全二叉树,然后逐步对其调整使其每个结点的值都大于其两个子结点的值,因此我们需要从第一个非叶结点开始逐步向前调整(叶结点不存在子结点比其大的状况,所以从非叶结点往前调整),假设一共有n个元素,那么第一个调整的结点为n/2。

  (2)交换并调整

  每次调整后将第一个最大的结点跟尾结点换位,则每一轮都是最大的在末尾,然后再次堆第一个结点进行调整,使得成为大顶堆,然后再次交换并调整,以此往复。

void shift(int a[], int low, int high){
    //对数组中处于low位的结点进行一次向下调整
    int temp = a[low];
    int i = low, j = 2*i; //i为待调整结点,j为i的子结点,
    while(j <= high){
        //若i没有子结点则跳出循环
        if(a[j] < a[j+1]) //跟子结点中较大的比较
            j++;
        if(a[j] > temp){ //大顶堆子结点较大就跟双亲结点换位
            a[i] = a[j];
            i = j;
            j = 2 * i;
        }
        else
            break;
    }
    a[i] = temp;
}
void heapSort(int a[], int n){
    //数组下标从1开始
    int i;
    int temp;
    for (i = n/2; i >= 1; --i) //建堆,从第一个非页结点即n/2开始逐步往前调整
    {
        shift(a, i, n);
    }
    
    for (i = n; i >= 2; ++i)//调整的第二个结点就行了,后面n-1个结点有序,且较大
    {
        tmep = a[1];//每次调整后将第一个最大的跟尾结点换位,则每一轮都是最大的在末尾
        a[1] = a[i];
        a[i] = temp;
        shift(a, 1, n-1);
    }
}
原文地址:https://www.cnblogs.com/leonandyou/p/11312492.html