希尔排序
一、概念
基础概念:希尔排序(shell sort)这个排序方法又称为缩小增量排序,是1959年D·L·Shell提出来的。该方法的基本思想是:设待排序元素序列有n个元素,首先取一个整数increment(小于n)作为间隔将全部元素分为increment个子序列,所有距离为increment的元素放在同一个子序列中,在每一个子序列中分别实行直接插入排序。然后缩小间隔increment,重复上述子序列划分和排序工作。直到最后取increment=1,将所有元素放在同一个子序列中排序为止。
通俗理解:
- 每次根绝增量increment的大小,根绝 + / - 增量找到间隔为 | increment | 的数组内的其他元素,然后把这些距离都为 | increment | 的元素组成一个子序列。 对这个子序列内部在进行插入排序,直至各个子序列内部都有序。
- 然后缩小增量(也就是缩小increment的值)。直到 increment = 1 这个时候就退化成了插入排序。但是由于前面对各个子序列内部进行排序 所以这个排序过程并不会太慢。
二、代码及过程
/**
*
*希尔排序
*
*Date:2019年5月1日
*
***/
#include <stdio.h>
void shellSort(int *a,int n){
int i,j;
int increment;
int temp;
// 这层循环控制增量,每循环一次就缩小增量除2,直到为0
for(increment = n / 2; increment > 0; increment /= 2){
// 这层循环负责比对当前增量下的子序列,每循环一次,代表比对完一组子序列
for(i = increment; i < n; i++){
temp = a[i];
// 这层循环负责每组子序列之间的比对
for(j = i - increment; j >= 0 && temp < a[j]; j -= increment){
a[j+increment] = a[j];
}
a[j+increment] = temp; // 找到第一个位置插入
}
}
}
void show(int *a,int n){
int i;
for(i = 0; i < n; i++){
printf("%3d",a[i]);
}
}
void main(){
int a[] = {21,25,49,25,16,-8,10};
int n = sizeof(a) / sizeof(a[0]);
printf("\n排序前:\n");
show(a,n);
// 希尔排序
shellSort(a,n);
printf("\n排序后:\n");
show(a,n);
printf("\n");
}
三、复杂度
时间复杂度: O(nlog2n)
空间复杂度: O(1)