从直接插入排序到希尔排序

Posted goodswarm

tags:

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

从直接插入排序到希尔排序

直接插入排序,它的原理就是把前i个长度的序列变成有序序列,然后循环迭代,直至整个序列都变为有序的。但是说来说去它还是一个时间复杂度为(n^2)的算法,难道就不能再进一步把时间复杂度降低一阶么?
希尔排序是希尔(Donald Shell)于1959年提出的一种排序算法。希尔排序也是一种插入排序,它是直接插入排序经过改进之后的一个更高效的版本,也称为缩小增量排序,同时该算法是冲破O(n2)的第一批算法之一。
算法思想的出发点:(直接插入排序)

  • 在基本有序时,效率较高
  • 在待排序的记录个数较少时,效率较高

那么:先将整个待排记录序列分割成若干子序列,分别进行直接插入排序,待整个序列中的记录“基本有序”时再对全体记录进行一次直接插入排序
???子序列是所有距离为dk倍数的记录(下面有详细流程)

与直接插入排序相比,希尔排序多了一个划分子序列的步骤。对比直接插入排序与希尔排序的代码,可以轻松理解希尔算法实现。

希尔算法的流程

以一个具体的例子来理解整个的算法:
技术图片

【初态:输入数据,dk为步长,即切片的增量】
由初态到第一趟结果的过程(从小到大排序):
技术图片

【黄色:初态数据和第一趟的序列分组,红色:第一趟结果数据和第一趟序列结果数据】
由第一趟结果到第二趟结果(从小到大排序):
技术图片

  1. 一种不稳定的排序方法
  2. 一次排序后元素的位置并不在最终结果的位置上

希尔算法的性能分析

  • Space Complexity:????S(n)=O(1)??????
  • Time Complexity:??????取决于增量序列(平均性能优于直接插入排序)

Code

int shellSort(int arr[], int n)
{
??? //gap为每一趟的长,倍减
??? for (int gap = n/2; gap > 0; gap /= 2)
??? {
??????? // gap sorted(直接插入排序)
??????? for (int i = gap; i < n; i += 1)
??????? {
??????????? // 直接排序从下标为零的元素开始
??????????? int temp = arr[i];
??????????? int j;
??????????? for (j = i; j >= gap && arr[j - gap] > temp; j -= gap)
                arr[j] = arr[j - gap];
??????????? //? put temp (the original a[i]) in its correct location
??????????? arr[j] = temp;
??????? }
??? }
??? return 0;
}

应试知识点

  • 希尔排序的流程
    • 正向:写出某趟的排序结果
    • 逆向:根据排序结果推理出增量间隔
  • 希尔排序的特点
    • 不稳定排序
    • 局部有序(每趟排序不一定将一个元素方置在最终的位置上)

以上是关于从直接插入排序到希尔排序的主要内容,如果未能解决你的问题,请参考以下文章

算法3 七大排序之:直接插入排序和希尔排序

插入排序(直接插入排序和希尔排序)

排序算法学习(直接插入排序,希尔排序,选择排序,堆排序,冒泡排序)

数据结构(四十四)插入排序(1.直接插入排序 2.希尔排序)

直接插入折半插入希尔排序

直接插入折半插入希尔排序