希尔排序其实就是有一个增量将数组分组,在组内进行插入排序,然后增量不断变小,最后为1,所以最后一趟就是为插入排序,但是最后一趟已经基本有序了,所以速度会比插入排序快一些。
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
这是希尔排序的代码实现
public static void shellSort(int[] arr) {
//其实就是插入排序 但是下标不是从1开始 从增量开始,只不过是根据增量分的组在组里进行插排
//只是外面多了一层增量不断变小最后为1的循环插入排序
//这里增量一开始为数组长度的一半,然后每次/2
for(int interval=arr.length/2;interval>0;interval/=2){
for(int i=interval;i<arr.length;i++) {
int temp = arr[i];
int j = i-interval;
while(j>-1&&temp<arr[j]) {
arr[j+interval] = arr[j];
j-=interval;
}
arr[j+interval] = temp;
}
}
}
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------
这是插入排序的代码实现
public static void insertSort(int[] arr) {
for(int i=1;i<arr.length;i++) {
int temp = arr[i];
int j = i-1;
while(j>-1&&temp<arr[j]) {
arr[j+1] = arr[j];
j--;
}
arr[j+1] = temp;
}
}
根据观察两个排序算法的代码主体部分可以发现,希尔排序只是在插入排序外面多了一层增量逐渐变小的循环,还有一点就是里层的插入排序是从增量为索引下标开始进行,那么假如有9数据项的话,那么第一趟的插入排序则是在下标为0 4 1 5 2 6 3 7 048 159 (增量为4)这些组中进行,第二趟增量为2则是在下标为:0 2 1 3 0 2 4 1 3 5 0 2 4 6 1 3 5 7 0 2 4 6 8 1 3 5 7 9 这些组中进行插排,最后一趟增量为1,那么就是普通的插入排序
希尔排序的时间复杂度:外层的循环为每次折半可知为logn,内层循环是是n那么总的就是nlogn,所以为O(nlogn),但是这是最好的情况下的时间复杂度,所以它的时间复杂度介于O(nlogn)-O (n^2)之间。
所以希尔排序是不稳定的,因为两个相同的数可以分到不同的组,那么他们之间的位置就是会发生变化的,所以一般大范围交换的排序算法都是不稳定的。