【C语言】【十大排序算法】希尔排序

希尔排序(Shell Sort)的名称源于它的发明者Donald SHell。该算法时冲破二次时间屏障的第一批算法之一。它通过比较相距一定间隔的元素来完成排序,每趟比较所用的距离随着算法的进行而减小,直到只比较相邻元素的最后一趟排序为止。因此希尔排序也叫做“缩小增量排序(diminishing increment sort)”.

希尔排序(Shell Sort)的思想:

  1. 将待排序数组按照一定的间隔氛围多个子数组,每组分别进行插入排序。因此本质上属于插入排序
  2. 逐渐缩小间隔进行下一轮排列
  3. 最后一轮时,取间隔位1,相当于直接使用插入排序,但此时经过“宏观调控”数组基本有序,所以此时的插入排序秩序进行少量交换即可。

举例说明


给定一个数组[81, 94, 11, 96, 12, 35, 17, 95, 28, 58, 41, 75, 15]
 

  • 第一轮.总共有13个元素,第一轮以5为步长的元素为一组,进行插入排序:

比较第0个元素81,和其间隔为5的元素35,比较后交换,交换后结果为[35, 94, 11, 96, 12, 81, 17, 95, 28, 58, 41, 75, 15]
比较第1个元素94,和其间隔为5的元素17,比较后交换,交换后结果为[35, 17, 11, 96, 12, 81, 94, 95, 28, 58, 41, 75, 15]
比较第2个元素11,和其间隔为5的元素95,比较后交换,交换后结果为[35, 17, 11, 96, 12, 81, 94, 95, 28, 58, 41, 75, 15]
...
比较第4个元素12,和其间隔为5的元素58,比较后交换,交换后结果为[35, 17, 11, 28, 12, 81, 94, 95, 96, 58, 41, 75, 15]
注意,至此,第一轮交换尚未完毕,第一轮交换仍在继续
比较第5个元素81,和其间隔为5的元素41,比较后交换,交换后结果为[35, 17, 11, 28, 12, 41, 94, 95, 96, 58, 81, 75, 15]
比较第6个元素94,和其间隔为5的元素75,比较后交换,交换后结果为[35, 17, 11, 28, 12, 41, 75, 95, 96, 58, 81, 94, 15]
比较第7个元素95,和其间隔为5的元素15,比较后交换,交换后结果为[35, 17, 11, 28, 12, 41, 75, 15, 96, 58, 81, 94, 95]
至此,在第一轮交换中,最后一个元素被交换,第一轮交换结束。

  • 第二轮以3为步长的元素为一组,进行插入排序:

比较第0个元素35,和其间隔为3的元素28,比较后交换,交换后结果为[28, 12, 11, 35, 12, 41, 75, 15, 96, 58, 81, 94, 95]
比较第1个元素17,和其间隔为2的元素12,比较后交换,交换后结果为[28, 12, 11, 35, 17, 41, 75, 15, 96, 58, 81, 94, 95]
比较第2个元素11,和其间隔为2的元素41,比较后交换,交换后结果为[28, 12, 11, 35, 17, 41, 75, 15, 96, 58, 81, 94, 95]
...[28, 12, 11, 35, 17, 41, 75, 15, 96, 58, 81, 94, 95]
...[28, 12, 11, 35, 15, 41, 75, 17, 96, 58, 81, 94, 95]
...[28, 12, 11, 35, 15, 41, 75, 17, 96, 58, 81, 94, 95]
...[28, 12, 11, 35, 15, 41, 58, 17, 96, 75, 81, 94, 95]
...[28, 12, 11, 35, 15, 41, 58, 17, 96, 75, 81, 94, 95]
...[28, 12, 11, 35, 15, 41, 58, 17, 94, 75, 81, 96, 95]
...[28, 12, 11, 35, 15, 41, 58, 17, 94, 75, 81, 96, 95]
第二轮结束后的排序结果为[28, 12, 11, 35, 15, 41, 58, 17, 94, 75, 81, 96, 95]

  • 最后一轮,以步长为1进行插入排序

最后一轮结束后的排序结果为:[11, 12, 15, 17, 28, 35, 41, 58, 75, 81, 94, 95, 96]

C语言实现

#include <stdio.h>

void shellSort(int* nums, int numsSize) {
    int i, j, increment, tmp;
    for (increment = numsSize / 2; increment > 0; increment /= 2) {
        // 每次步长减半
        for (i = increment; i < numsSize; i++) {
            // 从i开始,以increment为步长,进行插入排序
            tmp = nums[i];
            for (j = i; j >= increment; j -= increment) {
                // 以increment步长的元素为一组,进行插入排序(从后向前扫描,遇到合适的位置则插入)
                if (tmp < nums[j - increment]) {
                    nums[j] = nums[j - increment];
                }
                else {
                    break;
                }
            }
            nums[j] = tmp;
        }
        printf("完成以步长为%d的排序,排序结果为:", increment);
        for (int i = 0; i < numsSize; i++) {
            printf("%d ", nums[i]);
        }
        printf("\n");
    }
}

int main() {
    printf("希尔排序算法(Shell Sort Algorithm)\n");
    int a[] = {81, 94, 11, 96, 12, 35, 17, 95, 28, 58, 41, 75, 15};
    shellSort(a, 13);
    return 0;
}

代码运行结果:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

碧波bibo

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

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

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

打赏作者

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

抵扣说明:

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

余额充值