四、希尔排序->改进版插入排序

希尔排序,是插入排序的改进版。将数组内的值隔一段距离取出来当成一个新的数组排序,按照一定的间隔将整个数组排序完成后,缩小间隔在排序,一直到间隔为一的时候再排一次。那么这个时候排序完成。

 如上图所示是间隔为4的时候进行排序,然后缩短间隔重复上边的步骤即可,一直缩短间隔到1的时候停止循环,这个时候就完成了排序。

直接看代码吧

package bubbling;

/**
 * <p>希尔排序</p>
 *
 * @author zy 刘会发
 * @version 1.0
 * @since 2020/4/11
 */
public class ShellSort {

    static void sort(int[] arr) {
        for (int w = 4; w > 0; w /= 2) {
            for (int i = w; i < arr.length; i++) {
                for (int j = i; j > w - 1; j -= w) {
                    if (arr[j] < arr[j - w]) exchange(arr, j, j - w);
                }
            }
        }
        print(arr);

    }

    /**
     * 交换
     *
     * @param a 要交换位置的数组
     * @param i 要交换的位置(正确的位置)
     * @param j 最小值所在的位置
     */
    static void exchange(int[] a, int i, int j) {
        int temp = a[i];//用temp 最为第三方变量存储正确位置的值
        a[i] = a[j];//将正确的值放到正确的位置
        a[j] = temp;
    }

    static void print(int a[]) {
        for (int i = 0; i < a.length; i++) {
            System.out.print(a[i] + ",");
        }
    }

    public static void main(String[] args) {
        int[] arr = new int[]{9, 6, 11, 3, 5, 12, 8, 7, 10, 15, 14, 4, 1, 13, 2};
        sort(arr);
    }
}

这样的话是最初以间隔为4开始循环,每次除以2,也就是说第二次间隔为2,以此类推,这样就完成了排序。但是实际情况下间隔也不一定为4,有可能数组很大,那么以4为间隔就不太合适了。

最初的方式是将数组对半分开,无限分下去,直到不能再分。

package bubbling;

/**
 * <p>希尔排序</p>
 *
 * @author zy 刘会发
 * @version 1.0
 * @since 2020/4/11
 */
public class ShellSort {

    static void sort(int[] arr) {
        for (int w = arr.length / 2; w > 0; w /= 2) {
            for (int i = w; i < arr.length; i++) {
                for (int j = i; j > w - 1; j -= w) {
                    if (arr[j] < arr[j - w]) exchange(arr, j, j - w);
                }
            }
        }
        print(arr);
    }

    /**
     * 交换
     *
     * @param a 要交换位置的数组
     * @param i 要交换的位置(正确的位置)
     * @param j 最小值所在的位置
     */
    static void exchange(int[] a, int i, int j) {
        int temp = a[i];//用temp 最为第三方变量存储正确位置的值
        a[i] = a[j];//将正确的值放到正确的位置
        a[j] = temp;
    }

    static void print(int a[]) {
        for (int i = 0; i < a.length; i++) {
            System.out.print(a[i] + ",");
        }
    }

    public static void main(String[] args) {
        int[] arr = new int[]{9, 6, 11, 3, 5, 12, 8, 7, 10, 15, 14, 4, 1, 13, 2};
        sort(arr);
    }
}

这种方式比较简单,据说希尔最初也是用这种方式的,但是有人提出了一个更好的序列来作为间隔!那就是Knuth序列

他张这个样子

h=1;
h=h*3+1;

有没有很眼熟?高中的时候没有有见过?

package bubbling;

/**
 * <p>希尔排序</p>
 *
 * @author zy 刘会发
 * @version 1.0
 * @since 2020/4/11
 */
public class ShellSort {

    static void sort(int[] arr) {
        int h = 1;
        while (h <= arr.length / 3) {
            h = h * 3 + 1;
        }
       
        for (int w = h; w > 0; w = (w - 1) / 3) {
            for (int i = w; i < arr.length; i++) {
                for (int j = i; j > w - 1; j -= w) {
                    if (arr[j] < arr[j - w]) exchange(arr, j, j - w);
                }
            }
        }
        print(arr);

    }

    /**
     * 交换
     *
     * @param a 要交换位置的数组
     * @param i 要交换的位置(正确的位置)
     * @param j 最小值所在的位置
     */
    static void exchange(int[] a, int i, int j) {
        int temp = a[i];//用temp 最为第三方变量存储正确位置的值
        a[i] = a[j];//将正确的值放到正确的位置
        a[j] = temp;
    }

    static void print(int a[]) {
        for (int i = 0; i < a.length; i++) {
            System.out.print(a[i] + ",");
        }
    }

    public static void main(String[] args) {
        int[] arr = new int[]{9, 6, 11, 3, 5, 12, 8, 7, 10, 15, 14, 4, 1, 13, 2};
        sort(arr);
    }
}

到此结束,文笔不好,还请见谅!!!欢迎吐槽!!!

原文地址:https://www.cnblogs.com/Tiandaochouqin1/p/12680563.html