排序算法C语言实现——堆排序

/*
堆排
nlog(n)
*/
/*堆排复杂度分析
1、建堆((n*log(n))/2)
    循环n/2次,每次调用HeapAdjust函数
    HeapAdjust内部循环log(n)
2、调整堆(((n-1)log(n))/2)
    循环n-1次,每次调用HeapAdjust函数
    HeapAdjust内部循环log(n)
3、综合1、2,去除常数,总的复杂度为nlog(n)
*/
/*
功能:调整堆中指定的节点
输入:data-待调整的堆;pos-待调整的节点;len-总节点数
输出:data-调后的堆
*/
void HeapAdjust(int *data, size_t pos, size_t len)
{
    size_t iChild=pos*2 + 1;
    int iTemp=data[pos];/*待调整的节点*/
   
    /*每次选取比iTemp大的最大的子节点上移
      直到没有更大的子节点(break),
      或者没有子节点(iChild>=len)时,退出循环,保存待调整节点
    */
    while(iChild < len)
    {
        if(((iChild+1) < len) && (data[iChild] < data[iChild+1]))
        {
            ++iChild;
        }
        else
        {
            ;
        }
       
        if(iTemp < data[iChild])
        {
            data[pos] = data[iChild];
        }
        else
        {
            break;
        }
       
        pos = iChild;
        iChild = pos*2 + 1;
    }
   
    data[pos] = iTemp;
}
void HeapSort(int* data, size_t len)
{
    size_t pos=0;
    int iTemp=0;
   
    if(NULL == data)
    {
        /*throw("Invalid Parameter");*/
        return;
    }
    if(len < 2)
    {
        return;
    }
    else
    {
        pos = len/2; /*从最后一个有孩子的节点开始建堆*/
    }
   
    /*建堆,此时pos标示待调整的节点*/
    while(pos != 0)
    {
        --pos;
        HeapAdjust(data, pos, len);
    }
   
    /*循环换出堆顶并调整堆,此时pos标示堆的最后一个节点*/
    for(pos=len-1; pos>0; --pos)
    {
        iTemp = data[0];
        data[0] = data[pos];
        data[pos] = iTemp;
        HeapAdjust(data, 0, pos);
    }
}
posted @ 2018-10-13 19:34  Jo_ZSM  阅读(761)  评论(0编辑  收藏  举报