插入排序的算法复杂度为O(n2),但如果序列为正序可提高到O(n),而且直接插入排序算法比较简单,希尔排序利用这两点得到了一种改进后的插入排序。
一. 算法描述
希尔排序:将无序数组分割为若干个子序列,子序列不是逐段分割的,而是相隔特定的增量的子序列,对各个子序列进行插入排序;然后再选择一个更小的增量,再将数组分割为多个子序列进行排序......最后选择增量为1,即使用直接插入排序,使最终数组成为有序。
增量的选择:在每趟的排序过程都有一个增量,至少满足一个规则 增量关系 d[1] > d[2] > d[3] >..> d[t] = 1 (t趟排序);根据增量序列的选取其时间复杂度也会有变化,这个不少论文进行了研究,在此处就不再深究;
本文采用首选增量为n/2,以此递推,每次增量为原先的1/2,直到增量为1;
下图详细讲解了一次希尔排序的过程:
![](https://img-my.csdn.net/uploads/201209/06/1346931476_8161.jpg)
![](https://img-my.csdn.net/uploads/201209/06/1346931514_9288.jpg)
二 代码
public class ShellSort {
static void shellSort(Integer[] sortList) {
int i, j, step;
int len = sortList.length;
// 步长除以2
for (step = len / 2; step > 0; step /= 2)
/**
* 分别对每个分组进行直接插入排序
*/
for (i = 0; i < step; i++)
{
for (j = i + step; j < len; j += step)
if (sortList[j] < sortList[j - step]) {
int temp = sortList[j];
int k = j - step;
while (k >= 0 && sortList[k] > temp) {
sortList[k + step] = sortList[k];
k -= step;
}
sortList[k + step] = temp;
}
}
}
public static void main(String[] args) {
Integer[] testArray = {23, 25, 12, 42, 35,2,3,34,5,2,6432,2465,5,3,2,79,9,65,0,4,32};
ShellSort.shellSort(testArray);
System.out.println("The result is:");
for (Integer item : testArray) {
System.out.print(item);
System.out.print(' ');
}
}
}
运行结果