67-希尔排序

又称缩小增量排序。

先选定一个整数gap(动态步长),将待排序的数据中所有记录按gap分组。所有距离为gap的数据放在同一组,将组内元素排序,然后不断缩小gap的大小直到变为1,当gap变为1时,整个数组已经近乎有序(直接插入排序最好的情况),调用普通插入排序统一排序即可。

  • 希尔排序是对直接插入排序的优化。
  • 当gap > 1时都是预排序,目的是让数组更接近于有序。当gap == 1时,数组已经接近有序了,这样就会很快。这样整体而言,就会达到优化的效果。

一般情况,gap的大小和分组的个数是相同的。

/**
 * 希尔排序
 * @param arr
 */
public static void shellSort(int[] arr) {
    int gap = arr.length >> 1;
    while(gap > 1) {
        //不断按照Gap分组,组内按照插入排序
        insertionSortGap(arr, gap);
        gap /= 2;
    }
    //整个数组的插入排序
    insertionSortGap(arr,1);
}

/**
 * 按gap分组,组内按插入排序
 * @param arr
 * @param gap
 */
private static void insertionSortGap(int[] arr, int gap) {
    //外层从gap索引处开始不断向后走到数组末尾
    //i = 4
    for (int i = gap; i < arr.length; i++) {
        //内层从gap索引开始向前看,看的元素就是距离他gap长度的元素
        //不断比较当前元素和前面gap元素的大小
        //j - gap >= 0,说明前面数组还有相同距离的元素,比较arr[j] 和 arr[j - gap]的大小
        //j = 9
        for (int j = i; j - gap >= 0 && arr[j] < arr[j - gap] ; j = j - gap) {
            swap(arr, j, j - gap);
        }
    }
}

 i从gap开始,比较是向前比,而不是向后比:不断向前比的原因在于,这样才能把最小值放在最前面。

稳定性:不稳定。

时间复杂度:O(n^(1.2) ~ O(nlogn))

你可能感兴趣的:(Java数据结构,算法,排序算法,数据结构)