希尔排序

87 阅读1分钟
**
 * 希尔排序排序
 * 个人理解:1.可以理解为直接插入排序的升级版,直接插入排序在数据量大的情况下,且基本无序的情况下,效率会很低
 *  2.希尔排序每次先将队列分组,分组基于增量gapgap=arr.length/3+1,此处并非一定用3,但是实验证明用3最好),
 *     然后使用直接插入排序完再次分组,分组增量gapgap=gap/3+1),直到gap=1,最后一次插入排序结束
 *  3.时间复杂度,因为每次排序次数不定,所以实验推出最好情况O(n~1.3),最坏情况O(n~1.5)
 *  3.空间复杂度和插入排序一样,因为没有用的额外空间,所以为0(1)
 *  4.稳定性,因为发生跳跃式变换(跳跃式指非相邻元素交换位置),所以不稳定
 */
public class SortTest {

    public static void main(String[] args) {
        int[] arr = {70, 12, 82, 43, 99, 23, 38, 53, 22};
        shellSort(arr);
        Arrays.stream(arr).forEach(System.out::println);
    }

    public static void shellSort(int[] arr) {
        int gap = arr.length - 1;
        while (gap > 1) {
            gap = gap/3 + 1;
            insertSort(arr, gap);
        }
    }

    /**
     * 基于增量的直接插入排序,将gap替换为1,就是直接插入排序算法的代码
     * @param arr
     * @param gap
     */
    public static void insertSort(int[] arr, int gap) {
        for (int i=1; i<arr.length; i++) {
            int temp = arr[i];
            int j = i-gap;

            for (; j>=0; j-=gap) {
                if (temp < arr[j]) {
                    arr[j+gap] = arr[j];
                } else {
                    break;
                }
            }

            arr[j+gap] = temp;
        }
    }

}