具体思路:
1.设置增量,依据增量把数组分成若干组
2.每次遍历将每个组依次进行插入排序
3.改变增量大小(重复执行2,3步骤)
示例代码:
#include <stdio.h>
#include <math.h>
void shellSort(int a[], int n) {
int gap = n;
while (gap != 0) {
gap = floor(gap/2);//增量为gap,gap不断缩小为本身的二分之一 ,用floor()函数,保证gap最后都能取到1,确保算法正确性
for (int i = 0; i < gap; i++) { //可知增量的大小即为组数,将数组分成了gap组
for (int j = i+gap; j < n; j += gap) { //对每一组进行插入排序
if (a[j] < a[j-gap]) {
int k = j-gap;
int tmp = a[j];
while (a[k] > tmp && k >= 0) {
a[k+gap] = a[k];
k -= gap;
}
a[k+gap] = tmp;
}
}
}
}
}
int main() {
int a[10],n = 10;
for (int i = 0; i < n; i++)
scanf("%d", &a[i]);
shellSort(a, n);
for (int j = 0; j < n; j++)
printf("%d ", a[j]);
printf("\n");
return 0;
}
算法分析:
第一次比较次数,每组2个元素:1*n/2
第二次比较次数,每组4个元素:最坏(1+2+3)*n/4
第三次比较次数,每组8个元素:最坏(1+2+3+……+7)*n/8
时间复杂度最坏情况为:O(n^2)
以下图示为转载内容
第1趟:(gap=4)
当gap=4时,意味着将数列分为4个组: {80,20},{30,10},{60,50},{40,70}。 对应数列: {80,30,60,40,20,10,50,70}
对这4个组分别进行排序,排序结果: {20,80},{10,30},{50,60},{40,70}。 对应数列: {20,10,50,40,80,30,60,70}
第2趟:(gap=2)
当gap=2时,意味着将数列分为2个组:{20,50,80,60}, {10,40,30,70}。 对应数列: {20,10,50,40,80,30,60,70}
注意:{20,50,80,60}实际上有两个有序的数列{20,80}和{50,60}组成。
{10,40,30,70}实际上有两个有序的数列{10,30}和{40,70}组成。
对这2个组分别进行排序,排序结果:{20,50,60,80}, {10,30,40,70}。 对应数列: {20,10,50,30,60,40,80,70}
第3趟:(gap=1)
当gap=1时,意味着将数列分为1个组:{20,10,50,30,60,40,80,70}
注意:{20,10,50,30,60,40,80,70}实际上有两个有序的数列{20,50,60,80}和{10,30,40,70}组成。
对这1个组分别进行排序,排序结果:{10,20,30,40,50,60,70,80}