希尔排序
欢迎关注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;
}
}
标签:idx,插入排序,gap,希尔,arrs,序列,排序
From: https://www.cnblogs.com/xiguan/p/17274246.html