1.基本思想 希尔排序是基于插入排序的,又叫缩小增量排序。 在插入排序中,标记符左边的元素是有序的,右边的是没有排过虚的这个算法取出标记符所指向的数据,存入一个临时变量,然后再缩编有序的数组红找到临时变量应该插入的位置,然后将插入位置之后的元素依次后移一位,最后插入临时变量中的数据,试想,假如有一个很小的数据项再靠近右端的位置上,把这个数据项插入到有序数组中时,将会有大量的中间数据项需要右移一位,这个步骤对每个数据项都执行了将近N次复制。虽然不是所有数据项都必须移动N个位置,但是,数据项平均移动了N/2个位置,一共N个元素,总共是N2/2次复制,这实际上是一个很耗时的过程,希尔排序就是对这一步骤进行了改进,不必一个个的移动所有中间数据项,就能把较小的数据项移动到左边,大大提高了排序效率。 希尔排序通过加大插入排序时元素之间的间隔,并对这些间隔的元素进行插入排序,从而使数据能大跨度地移动。数据项之间的间隔被称为增量,习惯上还用gap表示。
2.实例(交换法实现)
public class ShellSort {
public static void main(String[] args) {
int[] arr = {8,9,1,7,2,3,5,4,6,0};
shellSort(arr);
}
public static void shellSort(int[] arr){
int temp = 0;
int count = 0;
for (int gap = arr.length / 2; gap > 0; gap /=2){
for (int i = gap; i < arr.length; i++) {
for (int j = i-gap; j >=0 ; j -= gap) {
if (arr[j] > arr[j+gap]){
temp = arr[j];
arr[j] = arr[j + gap];
arr[j + gap] = temp;
}
}
}
System.out.println("第"+(++count)+"轮进行排序后:"+ Arrays.toString(arr));
}
}
}
实验结果
3.算法分析
希尔排序不像其他时间复杂度为O(N log2N)的排序算法那么快,但是比选择排序和插入排序这种时间复杂度为O(N2)的排序算法还是要快得多,而且非常容易实现。它在最坏情况下的执行效率和在平均情况下的执行效率相比不会降低多少,而快速排序除非采取特殊措施,否则在最坏情况下的执行效率变得非常差。 迄今为止,还无法从理论上精准地分析希尔排序的效率,有各种各样基于试验的评估,估计它的时间级介于O(N3/2)与O(N7/6)之间。我们可以认为希尔排序的平均时间复杂度为O(N*(logN)2)。
|