希尔排序

希尔排序

基本思想

希尔排序(Shell's Sort)是插入排序的一种又称“缩小增量排序”(Diminishing Increment Sort),是直接插入排序算法的一种更高效的改进版本。希尔排序是非稳定排序算法。该方法因 D.L.Shell 于 1959 年提出而得名。

希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至 1 时,整个文件恰被分成一组,算法便终止。

实现步骤

  1. 先将数组分为n/2组对每一组进行简单的插入排序

  2. 再将数组分为n/2/2组,对每一组进行简单的插入排序

  3. 同上……

  4. 直到只剩余一组时,执行最后一次排序,算法终止

    注意:分组是,每组的元素不是连续的,第一组是以n/2为步长分组,其余的以此类推,不断除以2,直至为1进行最后一次排序

    分类:希尔排序分为两种,交换法(不推荐),移位法(更优)

    建议:先看懂插入排序再看希尔排序,

代码实现

//移位式希尔排序
public static int[] sortRemove(int[] arr){
    int n=arr.length/2;
    while(n>=1){
        for(int i=n;i< arr.length;i++){//起始为每组的第二个数
            int index=i-n;//待插入下标,初始值为前部分有序列表的最后一个值
            int insertValue=arr[i];//待插入值
            while(index>=0 && insertValue<arr[index]){//找出待插入值的位置
                arr[index+n]=arr[index];
                index-=n;
            }
            arr[index+n]=insertValue;//index+n是由于上面循环的最后index-n;
        }
        n/=2;
    }
    return arr;
}

//交换式希尔排序
    public static int[] sortXi(int[] arr){
        int n=arr.length/2;
        while(n>=1){
            for(int i=n;i< arr.length;i++){//起始为每组的第二个数
                for(int j=i-n;j>=0;j-=n){//起始为每组的第一个数;内部实现类似于选择排序,将最小的数不断向前放,但全都遍历
                    if(arr[j]>arr[j+n]){
                        arr[j]=arr[j]^arr[j+n];
                        arr[j+n]=arr[j+n]^arr[j];
                        arr[j]=arr[j]^arr[j+n];
                    }
                }
            }
            n/=2;
        }
        return arr;
    }

复杂度与稳定性

稳定性:若数组中出现重复元素,若排序后重复元素还按照源数组中的先后顺序排列,则称之为稳定,否则为不稳定

in-place:不占用额外内存

n:数据规模

排序算法 平均时间复杂度 最好情况 最坏情况 空间复杂度 排序方式 稳定性
希尔排序 O(n log n) O(n log^2 n) O(n log^2 n) O(1) in-place 稳定

posted on 2021-04-29 10:49  凡人精灵  阅读(59)  评论(0编辑  收藏  举报

导航