写点什么

手写希尔排序算法

发布于: 53 分钟前

昨天给大家介绍了插入排序算法,今天介绍的希尔排序算法,其实是插入排序算法的更高效改进版。该算法因 D.L.Shell 于 1959 年提出而得名。


希尔排序是基于插入排序的以下两点性质而提出改进方法的:

  • 插入排序在对几乎已经排好序的数据操作时,效率高,即可以达到线性排序的效率;

  • 但插入排序一般来说是低效的,因为插入排序每次只能将数据移动一位;


希尔排序的基本思想是:

先将整个待排序的记录序列分割成为若干子序列分别进行直接插入排序,待整个序列中的记录"基本有序"时,再对全体记录进行依次直接插入排序。


希尔排序算法的原理,我们用图来解说。


一个未排序的数组,10 个元素,如下:


我们先用 N/2 =5 作为步长,将数据分为 5 组:


对每组数据进行直接插入排序:


然后再将步长/2, 作为新的步长,进行数据分组:


对每组数据进行直接插入排序:


然后再将步长/2, 作为新的步长,进行数据分组(此时 step 等于 1,是最后一次了):


最后再应用一次直接插入排序,整个数组就排好序了:


以上,就是希尔排序算法的图解​说明。


用程序实现时,对每个数据分组进行直接插入排序时,我们可以把多个分组​排序合并在一起,用一次循环就把多个分组都排好序。​具体思路为:

从下标等于 step 的元素开始,一直到整个数组的最后一个元素,对每个元素,从后向数组头部方向进行查找,用直接插入法将其插入到所在数据分组的​合适位置。同一个分组的元素,是与其距离为-step、-2*step​、-3*step...的元素。


希尔排序算法的​C 语言实现代码,如下:

void shell_sort(int* parr, int count) {    for (int step = count >> 1; step > 0; step >>= 1) { // 遍历每个元素,将其插入至所在分组的前面数据序列中        for (int i = step; i < count; i++) {            int val = parr[i];   // 待插入元素            int k = i;            while ((k - step >= 0) && (parr[k - step] > val)) { // 从后向前遍历所在分组, 比val大的元素向后移动一个位置                parr[k] = parr[k - step];                k -= step;            }            parr[k] = val;  // 插入至分组的相应位置        }    }}
复制代码


​我的微信号是 实力程序员,欢迎大家转发至朋友圈,分享给更多的朋友。

发布于: 53 分钟前阅读数: 3
用户头像

实力程序员,用实力说话! 2021.05.24 加入

超过20年一线产品研发和技术管理的实力程序员

评论 (1 条评论)

发布
用户头像
老师您好,我是图书策划编辑,想要邀请您写书,不知道您有没有这个意向呢
35 分钟前
回复
没有更多了
手写希尔排序算法