排序思路:
该算法是直接插入排序的优化算法。采用粗略排序到精确排序的思路,首先粗略的,按照步长step=len/2,选取元素(相距step远为一组)执行直接排序算法,此时元素都是两两为一组。排序好后,在将步长放短,step=step/2。依次类推。这样的好处在于,每次执行直接插入排序时,排序复杂度都会降低,减少了排序次数。
样例:
{22,35,16,9,5,20}
1)设定步长step=6/3=2,数组将从起始开始,每两个相邻step远的元素为一组。
{22,9}{35,5}{16,20}
执行直接排序后
{9,22}{5,35}{16,20}
结果:
{9,5,16,22,35,20}
共进行了3次排序。
2)设定步长step=2/2=1
直接对上述数组进行排序
{9,22,5,35,16,20}
{5,9,22,35,16,20}
{5,9,16,20,22,35}
3)排序结束。
分析过程可知,通过前期的步长分组,提前进行小组内的排序,为后续步骤打下基础,减少了后续的比较次数和排序步骤。Shell排序在数组规模较大时,表现要好于直接排序算法。
c实现:
void shellSort(int array[], int len){
int step = len/2;
int i,tmp;
while(step){
for(i=step; i<len; i++){
//每次i++都是各数组拉入一个新元素进行插入比较
tmp=array[i];
int j=i-step;
while(j>=0 && array[j]>tmp) {
array[j+step] = array[j];
j-=step;
}
array[j+step]=tmp;
}
step = step/2;
}
}
时间复杂度最差为O(n2),最好为O(n ^ (1.3) ) 。
Shell排序是不稳定排序,依赖于步长step,最佳时间复杂度需要推算,上述最好值参考自别处。