希尔排序

简述

        希尔排序(Shell Sort )是 D .L.希尔(D.L.Shell)提出的 "缩小增量" 的排序方法。它的作法不是每次一个元素挨一个元素的比较,而是初期选用大跨步(增量较大)间隔比较,使记录跳跃式接近它的排序位置;然后增量缩小,最后增量为 1 。这样记录移动次数大大减少,提高了排序效率。希尔排序对增量序列的选择没有严格规定。

算法思路

        1.先取一个正整数 d1(d1 < n) ,把全部记录分成 d1个组,所有距离为 d1的倍数的记录看成一组,然后在各组内进行插入排序;

        2.然后取 d2( d2 < d1 ) ;

        3.重复上述分组和排序操作,直到取 di = 1(i >= 1) ,即所有记录成为一个组为止。一般选 d1约为 n/2 , d2为 d1 / 2 , d3为 d2  / 2 ,…, d i = 1 ;

代码

#include <QDebug>
#include <QApplication>

void mDebug(int a[], int len)
{
    QString str;
    for (int i = 0; i < len; i++)
    {
        str += QString("%1 ").arg(a[i]);
    }
    qDebug() << str;
}

template<class T>
void ShellSort(T a[],int len)
{
    // k值代表前文中的增量
    int k = len / 2;

    // 方法一
    // 当增量k值变化到0,结束循环……
    while(k >= 1)
    {
        // i从k开始每次+1,a[i]与a[i-k]比较
        for(int i = k; i <= len; i++)
        {
            // 当a[i]小于a[i-k]时,则需要记住当前a[i]的值,这样有利于只用交换一遍
            if (a[i] < a[i - k])
            {
                int j = i;
                T temp = a[j];
                do
                {
                    a[j] = a[j - k];
                    j -= k;
                }while(j - k >= 0 && temp < a[j - k]);

                a[j] = temp;
            }
        }

        // 计算下一轮步长
        k = k / 2;
    }

//    // 方法二
//    // 当增量k值变化到0,结束循环……
//    while (k >= 1)
//    {
//        // i从k开始每次+1,a[i]与a[i-k]比较
//        for (int i = k; i < len; i++)
//        {
//            for (int j = i; j >= k && (a[j] < a[j - k]); j -= k)
//            {
//                T temp = a[j];
//                a[j] = a[j - k];
//                a[j - k] = temp;
//            }
//        }

//        // 计算下一轮步长
//        k = k / 2;
//    }
}

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    int s[] = {50, -1, 3, 4, 0, 5, 1000, 6, 7, 12, 8, 1, 2, 9, -530, 450, 77} ;
    int len = sizeof(s)/sizeof(s[0]);

    ShellSort(s, len);
    mDebug(s, len);

    return a.exec();
}

输出

"-530 -1 0 1 2 3 4 5 6 7 8 9 12 50 77 450 1000 "
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Ilson_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值