希尔排序(shell)

希尔排序(Shell Sort)是插入排序的一种。是针对直接插入排序算法的改进。该方法又称缩小增量排序,因DL.Shell于1959年提出而得名。

原理:希尔排序属于插入类排序,是将整个无序列分割成若干小的子序列分别进行插入排序。(其中增量值即为分区个数。)


以下这种方式较为好理解:--》代码借鉴他人

#include <stdio.h>
#include <stdlib.h>

//对单个组排序
int SortGroup(int* pnData, int nLen, int nBegin,int nStep)
{
    for (int i = nBegin + nStep; i < nLen; i += nStep)
    {
        //寻找i元素的位置,
        for (int j = nBegin; j < i; j+= nStep)
        {
            //如果比他小,则这里就是他的位置了
            if (pnData[i] < pnData[j])
            {
                int nTemp = pnData[i];
                for (int k = i; k > j; k -= nStep)
                {
                    pnData[k] = pnData[k - nStep];
                }
                pnData[j] = nTemp;
            }
        }
    }
    return 1;
}
//希尔排序, pnData要排序的数据, nLen数据的个数
int ShellSort(int* pnData, int nLen)
{
    //以nStep分组,nStep每次减为原来的一半。
    for (int nStep = nLen / 2; nStep > 0; nStep /= 2)
    {
        //对每个组进行排序
        for (int i = 0 ;i < nStep; ++i)
        {
            SortGroup(pnData, nLen, i, nStep);
        }
    }

    return 1;
}

int main()
{
    int nData[10] = {4,10,9,8,7,6,5,4,3,2};    //创建10个数据,测试
    ShellSort(nData, 10);        //调用希尔排序

    for (int i = 0; i < 10; ++i)        
    {
        printf("%d ", nData[i]);
    }

    printf("\n");
    system("pause");
    return 0;
}



方法二:


void ShellPass(SeqList R,int d)
   {//希尔排序中的一趟排序,d为当前增量
     for(i=d+1;i<=n;i++) //将R[d+1..n]分别插入各组当前的有序区---->此句需要注意
       if(R[i].key<R[i-d].key){
         R[0]=R[i];j=i-d; //R[0]只是暂存单元,不是哨兵
         do {//查找R[i]的插入位置
            R[j+d];=R[j]; //后移记录
            j=j-d; //查找前一记录
         }while(j>0&&R[0].key<R[j].key);
         R[j+d]=R[0]; //插入R[i]到正确的位置上
       } //endif
   } //ShellPass

  void  ShellSort(SeqList R)
   {
    int increment=n; //增量初值,不妨设n>0
    do {
          increment=increment/3+1; //求下一增量
          ShellPass(R,increment); //一趟增量为increment的Shell插入排序
       }while(increment>1)
    } //ShellSort

时间复杂度:介意 O(nlgn)~O(n2)

稳定性: 不稳定 ----》主要是跨度
个人理解  分,治(类似)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值