希尔排序
基本思想:先选定一个整数,把待排序文件中所有记录分成个几组,并对每一组内的记录进行排序。然后重复上述分组和排序的工作。直到=1时,所有记录在统一组内排好序。
- 分组插排:分组的个数从大到小,直到等于1最终插入排序
- 预排序:gap > 1
- 插排:gap == 1
gap = array.length
gap = gap / 3 + 1 或 gap = gap / 2
/**
* 希尔排序
*/
public class ShellSort {
private static void shellSortWithGap(int[] array, int gap){
//gap > 1 预排序
//gap == 1 插排
for(int i = 0; i < array.length; i++) {
int key = array[i];
int j = i - gap; //用来卡每个分组的边界值,方便分组内的数进行交换
for(; j >= 0 && key < array[j]; j = j-gap){
array[j - gap] = array[j]; //分组边界值交换
}
array[j + gap] = key;
}
}
public static void shellSort(int[] array) {
int gap = array.length;
while(true){
//gap = gap / 2;
gap = gap / 3 + 1;
shellSortWithGap(array , gap);
if(gap == 1){
break;
}
}
}
}
希尔排序特性总结:
- 希尔排序是对直接插入排序的优化
- gap > 1时都是预排序即为将数组分组插排,目的是让数组更接近有序,gap == 1时,数组已经非常接近有序,插排完成有序
- 时间复杂度:最好O(n),平均O(n^1.2~1.3),最坏O(n ^2)
- 空间复杂度:O(1)
- 稳定性:不稳定