标签:
1.原理
希尔排序又称为缩小增量排序,是一种插入排序,排序速度比直接插入排序更加快捷。
对于长度为n的待排序数组a,希尔排序的基本思路如下:
A.选取整数gap(0<gap<n),将所有距离为gap的元素分为一组,总计有gap组;
B.对各个数组进行直接插入排序,数组变得稍微有序;
C.重复步骤A和B,对数组不断进行分组和排序,直至gap=1,此时对整个数组进行直接插入排序,排序完成。
2.实例
待排序数组a:[8, 1, 4, 2, 7, 0, 9, 6, 3, 5]
第一次: 第二次:
gap=5,数组分类如下: gap=2,数组分类如下:
a:[8, 1, 4, 2, 7, 0, 9, 6, 3, 5] a:[0, 1, 4, 2, 5, 8, 9, 6, 3, 7]
A: 8 0 A: 0 4 5 9 3
B: 1 9 B: 1 2 8 6 7
C: 4 6 数组分为2组,对每组进行直接插入排序,结果如下:
D: 2 3 A: 0 3 4 5 9
E: 7 5 B: 1 2 6 7 8
数组分为5组,对每组进行直接插入排序,结果如下: a:[0, 1, 3, 2, 4, 6, 5, 7, 9, 8]
A:0 8
B: 1 9 第三次:
C: 4 6 gap=1,即对整个数组进行直接插入排序:
D: 2 3 a:[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
E: 5 7
a:[0, 1, 4, 2, 5, 8, 9, 6, 3, 7]
3.代码
public class ShellSortTest {
// 遍历数组
public static void printAll(int[] a) {
for (int value : a) {
System.out.print(value + "\t");
}
System.out.println();
}
//希尔排序
public static void shellSort(int a[]) {
int gap = a.length / 2; //取初始步长为n/2
while (gap>=1) {
// 把距离为 gap 的元素编为一个组
for (int i = gap; i < a.length; i++) {
int temp = a[i]; //待插元素
int j = i - gap;
// 对距离为 gap 的元素组进行直接插入排序
while ( j >= 0 && temp < a[j]) {
a[j + gap] = a[j]; //元素后移
j = j - gap;
}
a[j + gap] = temp; //在空出的位置插入待插元素
}
System.out.format("gap="+gap+":"+"\t");
printAll(a);
gap = gap / 2; // 减小增量
}
}
public static void main(String[] args) {
int a[]= { 8, 1, 4, 2, 7, 0, 9, 6, 3, 5 };
System.out.print("排序前:\t");
ShellSortTest.printAll(a);
ShellSortTest.shellSort(a);
System.out.print("排序后:\t");
ShellSortTest.printAll(a);
}
}
4.时间复杂度
希尔排序的时间复杂度与步长的选取有关,例如希尔增量时间复杂度为O(n²),而Hibbard增量的希尔排序的时间复杂度为O(),
希尔排序时间复杂度的下界是n*log2n。
标签:
原文地址:http://www.cnblogs.com/jfl-xx/p/4842520.html