Java学习笔记数据结构和算法分析

希尔排序思想与实现

2017-07-13  本文已影响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;
    }
}

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

上一篇下一篇

猜你喜欢

热点阅读