堆排序:

  是种特殊的选择排序

  堆是一种完全二叉树,满足 a[i]<=a[2i]  a[i]<=a[2i+1] (小顶堆)  或都大于(大顶堆)

      

  第一步:将数组变成大顶堆或是小顶堆

  第二部:将堆顶的元素与最后的一个元素进行互换,且将除去最后一个元素的数组变成一个大顶堆或是小顶堆,直到数组只有一个值停止

  

代码如下:

 

//堆排序
void heap(int unsort[], int waiti, int lenght)
{
    //当第一个元素为1开始时, 节点i的子节点为2*i和2*i+1  但是数组是从0开始的 所以又+1
    int childindex = waiti*2+1;
    int temp = unsort[waiti];
    while(childindex < lenght)
    {
        if(childindex+1 < lenght && unsort[childindex] < unsort[childindex+1])
        {
            childindex++;
        }
        //若子节点比父节点要大,则互换且对此节点进行判断,看是否符合大顶堆,若不是则此节点为大顶堆,直接退出,不需要再进行调整了
        if(unsort[waiti] < unsort[childindex])
        {
            unsort[waiti] = unsort[childindex];
            unsort[childindex] = temp;
            waiti = childindex;
            childindex = waiti*2+1;
        }
        else
        {
            break;
        }
    }

}

void heap_sort(int unsort[], int lenght)
{
    int len = lenght/2;
    //初始为大顶堆
    for(int i = lenght - 1; i >=0; i--)
    {
        heap(unsort, i, lenght);
    }
    //将大顶堆的顶与没排好序的数组进行互换,并且进行大顶堆的设置
    for(int i = lenght-1; i > 0; i--)
    {
        int tmep = unsort[0];
        unsort[0] = unsort[i];
        unsort[i] = tmep;
        heap(unsort, 0, i);
    }
}

 

注意:

  变成大顶堆或是小顶堆的时候:当前元素,左孩子节点,右孩子节点中最大或是最小的元素与父节点进行互换