希尔排序是一种直接插入排序的改进版,插入排序每次移动一位,移动效率较低,而希尔排序将数组分割成 n 份,每次移动 n 位, 因此相比插入排序要高效。当移动位数n等于1时,等同于(链接)。
假设:对于集合 N【len】进行希尔排序,将 N 分割成 n 份,进行一次插入排序,通常 n 初始值取 len / 2,之后每次取 n /= 2,直到 n = 1时,进行最后一次插入排序,排序结束。
第一轮分割排序:用数组distance【i】临时保存分割间距,即:n = len,distance[0] = n / 2,对元素N【k】,进行一轮插入排序
即:k = distance[0]; k < len; k += distance[0];
第 i 轮分割排序:此时分割间距为 distance[i],继续进行一轮插入排序
即:k = distance[i]; k < len; k += distance[i];当分割间距 distance[i] 为 1 时,进行最后一次插入排序。
下面用C编写希尔排序如下:
void shell_Sort(int *N, int len)
{
int n = len;
int k, *distance;
distance = (int *)malloc(sizeof(int) * (len/2));
if(!distance)
return;
for(k = 0; n > 1; k++) {
n = n/2;
distance[k] = n;
}
int i, dist, temp, j;
for(k = 0; distance[k] >= 1; k++) {
dist = distance[k];
// 开始插入排序,分割间距为 dist
for(i = dist; i < len; i = i + dist) {
if(N[i - dist] > N[i]) {
temp = N[i];
N[i] = N[i - dist];
j = i - dist;
while(j >= 0 && N[j] > temp) {
N[j + dist] = N[j];
j = j - dist;
}
N[j + dist] = temp;
}
}
}
free(distance);
distance = NULL;
}
输入序列 N[10] = {9, 4, 10, 8, 1, 7, 6, 5, 3, 0},将整个希尔排序过程打印如下: