复杂度

时间复杂度(平均) 时间复杂度(最好) 时间复杂度(最坏) 空间复杂度 稳定性 复杂性
O(n^1.3) O(n^1.3) O(n^1.3) O(1) 不稳定 较简单

思路

  1. 选定增量gap,基于增量gap对待排序数组进行划分
  • (gap既相当于划分出的数组个数,有相当于对每个划分数组相邻运算的距离)
  • (gap一般初始为数组长度/2, 每次循环gap/=2)
  1. 将1划分出的数组进行排序(基于插入排序)
  2. 缩小gap(gap/=2),划分数组,对划分出的数组继续进行排序
  3. 至gap==0时排序结束
  • 整体而言相当于对插入排序的一个优化,因为每次划分数组的排序都是基于上一次小划分进行的.所以对当前划分数组的插入排序时间复杂度较低

代码

public void shellSort(int[] nums){
    int gap = nums.length / 2;
    while(gap != 0){
        for(int i = 0; i < gap; i++){ //此步循环相当于遍历划分出的数组
            for(int j = i + gap; j < nums.length; j += gap){//对某个具体数组进行操作
                int k = j;
                while(k - gap >= 0 && nums[k - gap] > nums[k]){
                    swap(nums, k, k - gap);
                    k -= gap;
                }
            }
        }
        gap /= 2;
    }
}

附插入排序(基于swap)代码

public int[] insert(int[] nums){
    int[] temp = new int[nums.length];
    temp[0] = nums[0];
    for(int i = 1; i < nums.length; i++){
        for(int j = i - 1; j >= 0; j--){
            if(nums[i] < temp[j]){
                swap(temp, j, j + 1);
            }else {
                temp[j + 1] = nums[i];
                break;
            }
        }
    }
    return temp;
}

private void swap(int[] nums, int i, int j){
    int temp = nums[i];
    nums[i] = nums[j];
    nums[j] = temp;
}