堆排序

堆排序是对选择排序的优化,利用选择排序中的相对关系,减少比较次数。

堆排序主要分为两个部分,初始建堆过程和堆定点更替后堆的调整部分。

最好,最坏,平均时间复杂度都为O(nlogn),尽管如此,平均情况下,快排表现还是要好于堆排序。

本文以数组为堆的存储结构,数组从0下标开始。将数组非降序排序,其中使用大顶堆,每次最大元素换到最后,最后数组即为升序。

main部分

int main()
{
        const int iNum = 10;
        int iarry[] = {10,9,8,7,6,5,4,3,2,1};
        Run(iarry,iNum);
        for(int i=0; i<iNum; ++i)
        {
                printf("%d\t",iarry[i]);
        }
        printf("\n");
        return 0;
}

sort主体,其中iNum为数组长度,即最后元素下一位置。非叶子节点从iNum/2-1到0,需要调整堆结构。

void Run(int iarry[],int iNum)
{
        /*建堆过程,0下标即为最大值*/
        for(int i=iNum/2-1; i>=0; --i)
        {
                HeapAdjust(iarry,i,iNum);
        }
        int itmp;
        for(int i=iNum-1; i>0; --i)
        {
                /*最大值和i下标交换,次大值放到尾部,调整以新0下标元素为顶的堆*/
                itmp = iarry[0];
                iarry[0] = iarry[i];
                iarry[i] = itmp;
                HeapAdjust(iarry,0,i);
        }
}
调整推,很自然想到递归方式:下标0开始,ilen是数组长度。

void HeapAdjust(int iarry[],int ipos, int ilen)
{
        int j=(ipos+1)*2-1;
        if(j >= ilen)
                return;//递归终止
        if(j<ilen-1 && iarry[j]<iarry[j+1])
        {
                j++;
        }
        if(iarry[ipos] >= iarry[j])
                return;//递归终止
        //swap
        int itmp = iarry[j];
        iarry[j] = iarry[ipos];
        iarry[ipos] = itmp;
        HeapAdjust(iarry, j, ilen);
}

非递归方式:

void HeapAdjust(int iarry[],int ipos, int ilen)
{
        int rc = iarry[ipos];
        for(int j=2*(ipos+1)-1; j<ilen; j*=2)
        {
                if(j<ilen-1 && iarry[j]<iarry[j+1]) 
                        ++j;
                if( rc>=iarry[j])
                        break;
                iarry[ipos] = iarry[j];
                ipos = j;
        }
        iarry[ipos] = rc;
}
非递归方式除了本身就比利用栈的递归快外,非递归相对递归方式还减少了赋值次数,递归方式最后需要交换对象。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值