希尔排序

Posted xigaun

tags:

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

希尔排序

欢迎关注fish的公众号:fish码农成长之旅

希尔排序也叫做递减增量排序算法,他是插入排序的高效改进版本。基本思想是将待排序的序列分成若干子序列分别进行插入排序,然后待整个序列基本有序的时候,再对整个序列排序。直观上看就是把数列进行分组(不停使用插入排序),直至从宏观上看起来有序,最后插入排序起来就容易了(无须多次移位或交换)。

算法步骤

首先我们选择一个增量序列,就是选择相隔多少位数为一个子序列,每次增量序列全部插入排序完之后,增量减少直到为1;gap1, gap2, gap3 ... gapk = 1。

按照我们的增量序列个数进行排序k次,每一次依据增量大小将整个序列分割成若干长度为m的子序列分别进行插入排序。

一次排序完成,增量减少,当增量为1时,整个序列作为一个表。

实例演示

总共7个数的排序,按照从小到大排序,原始数据为:3 38 5 1 9 4 10

首先第一次排序,按照gap=4将序列分为四组,每组元素在原来的索引上按照插入排序进行排序完成。
第二次排序gap=2将序列分为两组,依旧在原来的索引按照插入排序进行。
第三次gap=1,整个序列就相当于作一次插入排序。

代码实现

template <class T>
void shell_sort(std::vector<T> &arrs) 
  int n = arrs.size();  // 数组的大小
  if (n <= 1)          // 一个数的情况不需要排序
    return;
  

  int gap = (n + 1) / 2; // 首先按照俩个一组分个序列

  while (gap >= 1) 
    for (int idx_i = gap; idx_i < n; ++idx_i) 
      // 这里跟直接插入排序的区别就是每次idx_j要减去gap才能保证是对一个组的元素进行插入排序
      for (int idx_j = idx_i; idx_j >= gap && arrs[idx_j] < arrs[idx_j - gap];
           idx_j -= gap) 
        std::swap(arrs[idx_j], arrs[idx_j - gap]);
      
    

    gap /= 2;
  

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

希尔排序

希尔排序

希尔排序

6.4 希尔排序

希尔排序

基础排序算法三——希尔排序