希尔排序是插入排序的一种改进算法,又称缩小增量法。它通过将数组分成多个子数组来提高插入排序的效率。它的核心思想是:通过对数组元素进行分组排序,逐渐减少分组间隔,最终将整个数组排序。
如初始数据如下:64, 25, 12, 22, 11, 37, 96, 81, 34, 78, 68, 25, 27分组间隔为4
则其中64,11,34,27这4个之间进行比较;25,37,78这3个进行比较,然后12,96,68之间进行比较,最后22,81,25致敬进行比较,比较之后结果为11,25,12,22,27,37,68,25,34,78,96,81,64;
之后缩小分组间隔,重复此流程,得到最终结果。
最好的时间复杂度:当待排序数组已经部分有序时,希尔排序的时间复杂度可以接近 O(n log n)
,这取决于步长序列的选择。
最坏的空间复杂度:最坏情况下的时间复杂度为O(n²)。与插入排序相同,但是由于逐步缩小步长,通常性能会优于插入排序。
平均时间复杂度:一般情况下,希尔排序的平均时间复杂度在O(n^3/2)到 O(n²) 之间,一般只需记住O(n^3/2)即可,具体取决于步长序列。
其与插入排序相同,只是在原地排序,没有额外的占用空间,故空间复杂度为O(1)。
其优势在于通过减少步长来逐步优化排序过程,通常比标准插入排序要快。且时间复杂度在某些情况下比O(n²)更好,但它不是稳定排序,时间复杂度存在不确定性。
其java实现代码如下
import java.util.Arrays; // 添加Arrays类,用于输出数组内的全部内容
public class Main {
// 希尔排序的实现
public static void shellSort(int[] arr) {
int n = arr.length;
// 这里设置初始步长是数组长度的一半,之后不断减半
for (int gap = n / 2; gap > 0; gap /= 2) {
// 对当前步长的所有子数组进行插入排序
for (int i = gap; i < n; i++) {
int key = arr[i];
int j = i;
// 对子数组内的元素进行插入排序
while (j >= gap && arr[j - gap] > key) {
arr[j] = arr[j - gap];
j -= gap;
}
// 将key插入到合适的位置
arr[j] = key;
}
}
}
public static void main(String[] args) {
int[] arr = {64, 25, 12, 22, 11, 37, 96, 81, 34, 78, 68, 25, 27}; // 待排序的数组
System.out.println("排序前的数组:");
System.out.println(Arrays.toString(arr));
// 调用希尔排序方法进行排序
shellSort(arr);
System.out.println("排序后的数组:");
System.out.println(Arrays.toString(arr));
}
}
最终结果