手写希尔排序算法

Posted 实力程序员

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了手写希尔排序算法相关的知识,希望对你有一定的参考价值。

昨天给大家介绍了插入排序算法,今天介绍的希尔排序算法,其实是插入排序算法的更高效改进版。该算法因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; // 插入至分组的相应位置 } }}



以上是关于手写希尔排序算法的主要内容,如果未能解决你的问题,请参考以下文章

Java八股文面试题 基础篇 -- 二分查找算法冒泡排序选择排序插入排序希尔排序快速排序

Java八股文面试题 基础篇 -- 二分查找算法冒泡排序选择排序插入排序希尔排序快速排序

面试必备用Python手写十大经典排序算法

插入类排序—(折半)插入排序希尔排序

插入排序(直接插入排序折半插入排序希尔排序的算法思想及代码实现)

《算法》笔记 3 - 选择排序插入排序希尔排序