排序算法之希尔排序

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_38495686/article/details/79959226

1.基本思想

为了加快速度,简单地改进了插入排序,交换不相邻的元素以对数组的局部进行排序,并最终用插入排序将局部有序的数组排序

希尔排序的思想就是是使数组中任意间隔为h的元素都是有序的,这样的数组被称为h有序数组(如下图)。一个h有序数组就是h个互相独立的有序数组编织在一起的一个数组。在进行排序时,如果h很大,就将元素移动到很远的地方,为实现更小的h有序创造方便。用这种方式,对于任意的以1结尾的h序列,都能将数组排序

对于每个h,用插入排序将h个子数组独立地排序。但因为子数组是相互独立的的,一个更简单的方法是在h子数组中将每个元素交换到比它大的元素之前去

2.算法实现

希尔排序代码如下:

public class Shell {
    public static void sort(String[] a){
        int N = a.length;
        int h = 1;
        while(h < N/3)      h = 3*h + 1;
        while(h >= 1) {
            for(int i = h; i < N; i++) {
                for(int j = i; j >= h && less(a[j], a[j-h]); j -= h) {
                    exch(a, j, j-h);
                }
            }
            h = h/3;
        }
    }
    private static boolean less(String v, String w) {
        return v.compareTo(w) < 0;
    }
    private static void exch(String[] a, int i, int j){
        String t = a[i];
        a[i] = a[j];
        a[j] = t;
    }
    private static void show(String[] a){
        for(int i = 0; i < a.length; i++){
            StdOut.print(a[i] + " ");
        }
        StdOut.println();
    }
    public static boolean isSorted(String[] a){
        for(int i = 1; i < a.length; i++){
            if(less(a[i], a[i-1]))
                return false;
        }
        return true;
    }
    public static void main(String[] args){
        String[] a = {"a", "c", "e", "f", "d", "b"};
        StdOut.print("Before ShellSort: ");
        show(a);
        sort(a);
        assert isSorted(a);
        StdOut.print("After ShellSort:  ");
        show(a);
    }
}

3.结果展示

4.性能分析

希尔排序比插入排序和选择排序要快得多,并且数组越大,优势越大
使用递增序列1, 4, 13, 40, 121, 364…的希尔排序所需的比较次数不会超出N的若干倍乘以递增序列的长度。使用这个序列时间复杂度为 O(N^3/2)。

5.写在后面

如果有什么不对或建议,欢迎批评指正

阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页