希尔排序是插入排序的一种, 又称"缩小增量排序", 是插入排序算法的一种更高效的改进版本
原理:
    1、选定一个增长量h,按照增长量h作为数据分组的数据, 对数据进行分组
    2、对分好组的每一组数据完成插入排序
    3 减小增长量, 最小减为1, 重复第二步操作
增长量h的确定: 增长量h的值每一固定的规则, 采用以下规则: 
int h = 1;
while (h < 数组的长度 / 2) {
    h = 2 * h + 1}
// 循环结束后我们就可以确定h的最大值
h 的减小规则为:
    h = h / 2;

希尔排序-LMLPHP

实现类
public class Shell {

    /**
     * 对数据a中的元素进行选希尔序
     *
     * @param a
     */
    public static void sort(Comparable[] a) {
        // 1、根据数组a的长度, 确定增长量h的初始值
        int h = 1;
        while (h < a.length / 2) {
            h = 2 * h + 1;
        }

        // 2、希尔排序
        while (h >= 1) {
            // 排序
            // 2.1、找到待插入的元素
            for (int i = h; i < a.length; i++) {
                // 2.2、把待插入的元素插入到有序数组中
                for (int j = i; j >= h; j -= h) {
                    // 待插入的元素a[j],比较a[j]a[j - h]
                    if (greater(a[j - h], a[j])) {
                        // 交换元素
                        exchange(a, j - h, j);
                    } else {
                        // 待插入元素已经找到了合适的位置, 结束循环
                        break;
                    }
                }
            }
            // 减小h的值
            h = h / 2;
        }

    }

    /**
     * 比较v元素是否大于w元素
     *
     * @param v
     * @param w
     * @return
     */
    private static boolean greater(Comparable v, Comparable w) {
        return v.compareTo(w) > 0;
    }

    /**
     * 数据元素ij交换位置
     *
     * @param a
     * @param i
     * @param j
     */
    private static void exchange(Comparable[] a, int i, int j) {
        Comparable temp;
        temp = a[i];
        a[i] = a[j];
        a[j] = temp;
    }

}
测试类
public static void main(String[] args) {
    Integer[] a = {9, 1, 2, 5, 7, 4, 8, 6, 3, 5};
    Shell.sort(a);
    // 期望值: [1, 2, 3, 4, 5, 5, 6, 7, 8, 9]
    System.out.println(Arrays.toString(a));
}
03-08 06:52