希尔排序

希尔排序

希尔排序本身也是一种插入排序方法
基本思想:提升插入排序的效率,插入排序效率相对低下的原因是在插入过程中,当找到了待插入元素A[r+1]的位置k后,A[k].....A[r]都需要每次一步后移,为待插入元素腾位置,但是希尔排序通过设置步长,一次跳跃多步,避免一次一步这样慢慢的挪移,在后续的排序中,能够减少比较和移动的次数,以提高程序的效率

打个比方,数据A[1......r]是升序的,A[r+1] < A[1],如果是插入排序,那么要比较r次,并且移动r个数据,
才能为A[r+1]腾出位置,但是如果用希尔排序,那么A[r+1]会跳跃式前进,而移动数据的次数也小于r次,这也是为什么希尔排序的效率高于插入排序的原因。

算法逻辑:

nStep = n / 2;
WHILE(nStep >= 1)
          ShellSingleStepSort(pSrcData, nDataSize, nStep);    //按照某个步长,进行一次排序
          nStep = nStep / 2;
END FOR

 
对于单步排序,其实就是一个插入排序,但是该数据在数组中不是连续的,而是具有一定的间隔,也就是步长。

ShellSingleStepSort
输入:数组指针A, 数据大小size,步长step
输出:每个步长间隔的小序列都有序的数组

FOR I = step to size-1
    curVal = A[I]    
    FOR J = i - step; j >= 0; j=-step    //就是一个插入排序
            IF A[J] > curVal  THEN
                  A[J+step] = A[J]
            ELSE
                  BREAK;
            END IF
    END FOR
    A[J+step] = curVal
END FOR

算法实现

void ShellSingleStepSort(int* pSrcData, int nDataSize, int nStep)
{
        for (int j= nStep; j < nDataSize; j++)
        {
                int nTmp = pSrcData[j];
                int m = j - nStep;

                for ( ; m >= 0; m -= nStep)
                {
                        if (pSrcData[m] > nTmp)
                              pSrcData[m + nStep] = pSrcData[m];
                        else
                              break;
                }
                if (j != m + nStep)
                     pSrcData[m+nStep] = nTmp;
        }
}


//步长为:DataSize/2, DataSize/4, DataSize/8......1
void ShellSort(int* pSrcData, int nDataSize)
{
        int nStep = nDataSize / 2;

        while (nStep >= 1)
        {
                ShellSingleStepSort(pSrcData, nDataSize, nStep);
                nStep = nStep / 2;
        }
}

 

排序结果比较:

明显可以看出希尔排序的比较次数小于插入排序

 数据规模

InserationSort

ShellSort

100

2478

2211

500

63750

48099

1000

251094

189171

5000

6305769

4379758

10000

24953116

17153512

50000

624724636

510011290

转载于:https://my.oschina.net/myspaceNUAA/blog/68005

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值