希尔排序思想与实现

作者: 蜗先生 | 来源:发表于2017-07-13 16:48 被阅读123次

    希尔排序是对插入排序的修改,我们知道插入排序比选择排序更优,希尔排序又是比插入排序更优的一种方式,具体原因,看完下面的思想就知晓。

    插入排序是拿出无序队列中的第一个元素与有序队列进行比较,通过多次相邻交换插入到相应的位置。希尔排序改变了交换的两个元素之间的距离,与插入排序的相邻交换不同,希尔排序交换距离为h的元素,最终变成h有序数组(间隔为h的元素组成一个有序数组,原数组由h个有序数组组成),不断缩小h的值,当h最终变为1,就实现了原数组的排序。希尔排序增大了交换的跨度,所以减少了交换的次数,加快了排序的速度,另一方面因为不断减小h,增大了比较的次数。
    h有序数组的举例:
    h=3的序列1,6,11,2,7,12,3,8,13,4,9,14,5,10,15
    1 2 3 4 5
    6 7 8 9 10
    11 12 13 14 15

    例:1, 4, 10, 5, 4, 9, 12, 2
    初始值h=3

    h=3
    分三组
    1, 5, 12
    4, 4, 2
    10, 9
    对每组进行比较交换
    1, 5, 12
    2, 4, 4
    9, 10
    所得3有序数组1,2,9,5,4,10,12,4

    h=2
    分两组
    1, 9, 4, 12
    2, 5 10 4
    对每组进行比较交换
    1, 4, 9, 12
    2, 4, 5, 10
    所得2有序数组1,2,4,4,9,5,12,10

    h=1
    分一组
    1,2,4,4,9,5,12,10
    对该组比较交换
    1,2,4,4,5,9,10,12
    所得1有序数组1,2,4,4,5,9,10,12

    最终希尔排序结果1,2,4,4,5,9,10,12

    最后一次排序与插入排序算法相同,但是毋庸置疑交换次数减少了,加快了排序速度,数组长度越大,越能体现出希尔排序的优势。

    实现代码

    /**
     * 希尔排序:依次改变缩量的插入排序
     * 
     * @see 重复做的事:改变缩量,从无序序列中选择第一个元素,与有序序列交换位置,与有序序列比较
     * @param a
     */
    public static void shellSort(int[] a) {
        int h = 1;
        // 根据条件获取最大h
        while (h < a.length / 3) {
            h = h * 3;
        }
        // 缩小h并重复排序算法
        while (h >= 1) {
            // 拿出h之后的元素作为插入元素
            for (int i = h; i < a.length; i++) {
                // 与前面h个位置的元素交换位置直到找到一个小于当前值的元素
                for (int j = i; j >= h; j -= h) {
                    if (a[j] < a[j - h]) {
                        int temp = a[j];
                        a[j] = a[j - h];
                        a[j - h] = temp;
                    } else {
                        break;
                    }
                }
            }
            h = h / 3;
        }
    }
    

    扩展文章
    快速排序思想与实现
    常用四种排序算法的思想与实现

    相关文章

      网友评论

        本文标题:希尔排序思想与实现

        本文链接:https://www.haomeiwen.com/subject/efowhxtx.html