最新要闻

广告

手机

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

家电

每日观点:希尔排序

来源:博客园


【资料图】

希尔排序

欢迎关注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 void shell_sort(std::vector &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;  }}

关键词: