【排序】插入排序 & 希尔排序(改进)

文章目录

以从小到大排序为例进行说明。

插入排序

插入排序就是从前向后(i=1开始)进行选择,如果找到在i之前(分配一个j下标进行寻找)有比array[i]大的数据,那就将其移动到后面(j+1处),每次小循环直到j < 0为止,大循环直到i > array.length为止。

  • 小循环就是将i前面的元素进行遍历找出大的元素
  • 大循环就是遍历整个数组将i处的元素进行插入调整

时间复杂度

O(n^2^)

最坏的情况是:i 顺着把整个数组遍历一遍的同时,j 向前遍历每次都需要遍历至 -1;这样就会遍历n^2^次

  • 所以插入排序最快是排一个有序的数组,每次都不同调,是O(n)
  • 最慢是排一个逆序的数组,每次都需要遍历,是O(n^2^)

空间复杂度

O(1)

没有额外的空间消耗

代码

java 复制代码
public void insertSort(int[] array) {
        // 从1开始是因为一个元素必定是有序的
        for (int i = 1; i < array.length; i++) {
            // 保存下来用于比较,不然i下标的值可能会由于j+1的赋值而发生改变
            int tmp = array[i];
            // 从i的前一个开始比较
            int j = i - 1;
            for (; j >= 0; j--) {
                if (array[j] > tmp) {
                    // 如果比 tmp 大,那就应该将前一个数据挪到后一个
                    array[j+1] = array[j];
                } else {
                    // 如果小于等于,那就说明从这个j开始前面的都是有序的,不需要再遍历了
                    break;
                }
            }
            // 	循环结束后,插入 tmp 的值
            array[j+1] = tmp;
        }
    }

希尔排序

希尔排序是对于插入排序的改进,通过改变每次插入排序的间隔增量而达到优化的一种排序。

该排序定义了一个gap 用于标识每次插入排序的分组,其余于与插入排序无异。

时间复杂度

O(n^1.3^) ~ O(n^1.5^)

由于gap 的不同会导致排序的趟数不同,所以该算法并没有一个明确的时间复杂度。

空间复杂度

O(1)

没有额外空间开销

代码

java 复制代码
public void shellSort(int[] array) {
        int gap = array.length;
        // 循环每次的以gap为增量的插入排序
        while (gap != 1) {
            gap /= 2;
            shellSort(array, gap);
        }
    }

    private void shellSort(int[] array, int gap) {
    	// i+=gap也可以,因为最后gap传进来总会是1,会进行一次完全态的插入排序
        for (int i = 0; i < array.length; i++) {
            int tmp = array[i];
            int j = i - gap;
            // 这里就是对间隔为 gap 的数据进行比较和插入
            for (; j >= 0; j += gap) {
                if (array[j] > tmp) {
                    array[j + gap] = array[i];
                } else {
                    break;
                }
            }
            // 与普通插入排序相同,需要在最后将被比较的数据还到该去的地方
            array[j+gap] = tmp;
        }
    }
相关推荐
_GR13 分钟前
每日OJ题_牛客_牛牛冲钻五_模拟_C++_Java
java·数据结构·c++·算法·动态规划
ROBIN__dyc25 分钟前
表达式
算法
无限大.28 分钟前
c语言实例
c语言·数据结构·算法
六点半88833 分钟前
【C++】速通涉及 “vector” 的经典OJ编程题
开发语言·c++·算法·青少年编程·推荐算法
@haihi41 分钟前
冒泡排序,插入排序,快速排序,选择排序
数据结构·算法·排序算法
quaer44 分钟前
Open-Sora全面开源?
开发语言·算法·机器学习·matlab·矩阵
Hello.Reader1 小时前
TopK算法在大数据重复数据分析中的应用与挑战
大数据·算法·数据分析
coduck_S12004zbj1 小时前
csp-j模拟五补题报告
c++·算法·图论
丢掉幻想准备斗争1 小时前
数据结构(栈和队列的实现)
数据结构
洛临_1 小时前
【C语言】基础篇
c语言·算法