记排序算法(4)- 希尔排序

67 阅读1分钟

算法描述

先将整个待排序的记录序列分割成为若干子序列分别进行直接插入排序,步骤如下:

  • 选择一个增量序列t1,t2,…,tk,其中t1>t2,tk=1;一般t1取数组length/2,下图中的gap
  • 按增量序列个数k,对序列进行k 趟排序;
  • 每趟排序,根据对应的增量ti,将待排序列分割成若干长度为m 的子序列,分别对各子表进行直接插入排序。仅增量因子为1 时,整个序列作为一个表来处理,表长度即为整个序列的长度。

动画展示、

shell.gif

代码实现

public class ShellSort {
    public static void main(String[] args) {
        int[] a = new int[]{1,3,4,7,9,0,12,41,4,68,1,2,4};
        int length = a.length;
        int temp;
        for (int step = length/2; step>=1; step/=2){
            for (int i = step; i < length; i++){
                temp = a[i];
                int j = i - step;
                while (j>=0 && a[j]>temp){
                    a[j+step] = a[j];
                    j -=step;
                }
                a[j+step] = temp;
            }
        }
        Arrays.stream(a).forEach(System.out::println);
    }
}

总结

稳定性:算法不稳定,希尔排序在排序前后两个相等的数相对位置发生改变变。
时间复杂度:O(n^1.3),最好情况O(n), 最坏情况O(n^2)。
空间复杂度:O(1),不需要额外的变量进行存储。