希尔排序(Shell Sort)

希尔排序的原理:将待排序数据元素集合按照一定的大小分块在块间的数据按照增量(步长)进行直接插入排序,然后根据一定的规则减少步长,再进行一次直接插入排序,直到步长小于1 。

希尔排序需要注意的是最后的增量一定是1 。

下面先给出Java实现代码:

public static void shellSort(int array[]) {
        if (null == array || 1 >= array.length)
            return;
        int step = 0, n = array.length, temp, j;
        int len = n;
        do {
            step = (int) Math.sqrt(n);
            for (int i = step; i < len; i++) {
                temp = array[i];
                j = i - step;
                while (j >= 0 && temp < array[j]) {
                    array[j + step] = array[j];
                    j -= step;
                }
                array[j + step] = temp;
            }
            n = step;
        } while (step > 1);
    }
代码中初始步长为 Math.sqrt(n), n 为带排数据的长度,内部循环:

for (int i = step; i < len; i++) {
                temp = array[i];
                j = i - step;
                while (j >= 0 && temp < array[j]) {
                    array[j + step] = array[j];
                    j -= step;
                }
                array[j + step] = temp;
            }
是对一个特定的步长做一次直接插入排序,当step == 1 时,该待排序集合基本有序所以不用大量移动元素。
按照上面步骤对下列元素集合做希尔排序的过程如下:

集合R = {37, 40, 38, 42, 461, 5, 7, 9, 12}
第一趟排序取步长 step = 3 ,

希尔排序(Shell Sort)

途中使用了三种不同的标记,表示了步长中的每一个元素{Ri , Ri+1 , ... Ri+step -1} 。


第二趟排序取步长step = Math.sqrt(3) = 1 ;

得到最后排好序的序列: 5 , 7, 9,12, 37, 38,42,61 。


在上面的例子中比较特殊,之进行了两趟排序就完成了,而且每趟排序中元素个数都是相同的。而在实际使用中一般step取值为:

step = step/2.2 ;

希尔排序的时间复杂度:O(N^3/2)  到 O(N^7/6) .


希尔排序(Shell Sort)

上一篇:Openstack 自动化部署puppet代码管理


下一篇:iOS中的retainCount