希尔排序详解

        希尔排序实质上是一种分组插入方法。它的基本思想是:对于n个待排序的数列,取一个小于n的整数gap(gap被称为步长)将待排序元素分成若干个组子序列所有距离为gap的倍数的记录放在同一个组中;然后,对各组内的元素进行直接插入排序。 这一趟排序完成之后,每一个组的元素都是有序的。然后减小gap的值,并重复执行上述的分组和排序。重复这样的操作,当gap=1时,整个数列就是有序的。

详细例子见下图:

 图中10个元素,gap = 5,则对应下标的元素组成一个组:

下标为05组成一个组,即(1,0);

下标为16组成一个组,即(3,4);

下标为27组成一个组,即(8,6);

下标为38组成一个组,即(9,5);

下标为49组成一个组,即(2,7);

然后对在每个组内进行直接插入排序,则排序后的结果为:

下标为05组成一个组,即(0,1);

下标为16组成一个组,即(3,4);

下标为27组成一个组,即(6,8);

下标为38组成一个组,即(5,9);

下标为49组成一个组,即(2,7);

则排序后的整个序列为:

gap = 2,将上面序列分为2个组,则分成的组为:

 下标02468的元素组成一个组,即元素(0,6,2,4,9)组成一个组;

 下标13579的元素组成一个组,即元素(3,5,1,8,7)组成一个组;

然后对在每个组内进行直接插入排序,则排序后的结果为:

 下标02468的元素组成一个组,即元素(0,2,4,6,9)组成一个组;

 下标13579的元素组成一个组,即元素(1,3,5,7,8)组成一个组;

排序后整个序列为:

gap = 1,将上面的表组成一个表,对其进行插入排序操作,结果为:

 具体代码实现如下图所示:

#include<stdio.h>
void ShellSort(int arr[], int len)
{
    for (int gap = len / 2; gap > 0; gap /= 2) //gap为步长,每次减为原来一半
    {
        for (int i = 0; i < gap; i++) //gap个组,对每个组进行插入排序操作
        {
            //每组的第一个元素为有序序列,从每组的第二个元素与第一个元素进行比较插入适当位置,
            //其中每组的第一个元素对应的下标为i,第二个元素对应的下标为i + gap
            for (int j = i + gap; j < len; j += gap) //遍历无序序列中的元素
            {
                for (int k = i; k < j; k += gap)  //遍历有序序列中的元素一一与无序序列中的某个元素进行比较,执行插入操作
                {
                    if (arr[k] > arr[j])
                    {
                        int temp = arr[j];  // 保存无序序列中的元素
                        for (int m = j; m > k; m -= gap)  //将有序序列中从大于无序序列的第一个元素开始,所有的元素后移一位
                            arr[m] = arr[m - gap];
                        arr[k] = temp;
                    }
                }
                
            }
                
        }
    }
}

int main()
{
    int arrList[] = { 1, 3, 8, 9, 2, 0, 4, 6, 5, 7 };
    int length = (int)sizeof(arrList) / sizeof(arrList[0]);
    printf("排序前:   ");
    for (int i = 0; i < length; i++)
        printf("%d  ", arrList[i]);
    printf("\n");
    ShellSort(arrList, length);
    printf("排序后:   ");
    for (int i = 0; i < length; i++)
        printf("%d  ", arrList[i]);
    printf("\n");
    return 0;
}

 编译后结果如下图所示:

  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值