排序算法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)
*/
/*
功能:调整堆中指定的节点
输入:date-待调整的堆;pos-待调整的节点;len-总节点数
输出:date-调后的堆
*/
void HeapAdjust(int *date, size_t pos, size_t len)
{
    size_t iChild=pos*2 + 1;
    int iTemp=date[pos];/*待调整的节点*/
   
    /*每次选取比iTemp大的最大的子节点上移
      直到没有更大的子节点(break),
      或者没有子节点(iChild>=len)时,退出循环,保存待调整节点
    */
    while(iChild < len)
    {
        if(((iChild+1) < len) && (date[iChild] < date[iChild+1]))
        {
            ++iChild;
        }
        else
        {
            ;
        }
       
        if(iTemp < date[iChild])
        {
            date[pos] = date[iChild];
        }
        else
        {
            break;
        }
       
        pos = iChild;
        iChild = pos*2 + 1;
    }
   
    date[pos] = iTemp;
}
 
void HeapSort(int* date, size_t len)
{
    size_t pos=0;
    int iTemp=0;
   
    if(NULL == date)
    {
        /*throw("Invalid Parameter");*/
        return;
    }
    if(len < 2)
    {
        return;
    }
    else
    {
        pos = len/2 - 1; /*从最后一个有孩子的节点开始建堆*/
    }
   
    /*建堆,此时pos标示待调整的节点*/
    do
    {
        HeapAdjust(date, pos, len);
    }
    while((pos != 0) && --pos);
   
    /*循环换出堆顶并调整堆,此时pos标示堆的最后一个节点*/
    for(pos=len-1; pos>0; --pos)
    {
        iTemp = date[0];
        date[0] = date[pos];
        date[pos] = iTemp;
        HeapAdjust(date, 0, pos);
    }
}

猜你喜欢

转载自www.cnblogs.com/JoZSM/p/9783872.html