首页 > 编程语言 >【基础算法】排序算法 —— 插入排序

【基础算法】排序算法 —— 插入排序

时间:2023-10-04 23:44:06浏览次数:42  
标签:arr int 复杂度 插入 算法 排序 插入排序

一、算法原理

插入排序将数组分为已排序区间未排序区间,初始已排序区间只有数组第1个元素,未排序区间从下标 1 开始到数组末尾。每次取未排序区间的第1个元素,将它插入已排序区间的合适位置,并保证已排序区间一直有序。重复这个过程,直到未排序区间为空,算法结束。

给有序数组(已排序区间)插入1个新元素,并保持数组有序,应该都很熟悉。下图演示了给有序数组 [1,5,8] 插入 3 的过程,首先找到 3 应该在的位置,再把这个位置之后的元素全部向后移动一位,最后将 3 放在这个位置。

示例:使用插入排序对数组 arr = [4,5,6,3,2,1] 从小到大排序。

第1次插入:

第2次插入:

第3次插入:

第4次插入:

第5次插入:

二、代码实现

实现一

/**
 * 插入排序,时间复杂度 O(n^2),空间复杂度 O(1),稳定
 *
 * @param arr 待排序数组
 */
public static void insertSort(int[] arr) {
    if (arr == null || arr.length < 2) {
        return;
    }

    for (int i = 1, len = arr.length; i < len; i++) { // 未排序区间
        int j = i;
        while (j > 0 && arr[j] < arr[j - 1]) { // 查找未排序区间第1个元素,在已排序区间的合适位置,并交换
            swap(arr, j, j - 1);
            j--;
        }
    }
}

private static void swap(int[] arr, int i, int j) {
    if (i == j) {
        return;
    }
    arr[i] = arr[i] ^ arr[j];
    arr[j] = arr[i] ^ arr[j];
    arr[i] = arr[i] ^ arr[j];
}

实现二:

/**
 * 插入排序,时间复杂度 O(n^2),空间复杂度 O(1),稳定
 *
 * @param arr 待排序数组
 */
public static void insertSort(int[] arr) {
    if (arr == null || arr.length < 2) {
        return;
    }

    for (int i = 1, len = arr.length; i < len; i++) { // 未排序区间
        int cur = arr[i]; // 未排序区间第1个元素
        // 在已排序区间查找要插入的位置
        int j = i - 1;
        for (; j >= 0; j--) {
            if (cur < arr[j]) {
                arr[j + 1] = arr[j];
            } else {
                break;
            }
        }
        // 插入数据
        arr[j + 1] = cur;
    }
}

private static void swap(int[] arr, int i, int j) {
    if (i == j) {
        return;
    }
    arr[i] = arr[i] ^ arr[j];
    arr[j] = arr[i] ^ arr[j];
    arr[i] = arr[i] ^ arr[j];
}

 

三、算法评价

3.1 时间复杂度

最好时间复杂度:O(n)

最好情况下,要排序的数组已经是有序的,并不需要搬移任何数据。如果从后到前在已排序区间里查找插入位置,每次只需要比较一次就能确定插入的位置,而且不用做数据交换。所以这种情况下,最好时间复杂度为 O(n)。

最坏时间复杂度:O(n2)

最坏情况下,要排序的数组刚好是倒序排列的,每次插入都相当于在数组的第一个位置插入新元素,需要移动已排序区间的所有数据,所以最坏情况时间复杂度为 O(n2)。

平均时间复杂度:O(n2)

我们知道,在数组中插入一个数据的平均时间复杂度是 O(n)。所以,对于插入排序来说,每次插入操作都相当于在数组中插入一个数据,循环执行 n 次插入操作,所以平均时间复杂度为 O(n2)。

 

3.2 空间复杂度

插入排序算法的运行并不需要额外的存储空间,所以空间复杂度是 O(1),是一个原地排序算法。

 

3.3 稳定性

在插入排序中,对于值相同的元素,我们可以选择将后面出现的元素,插入到前面出现元素的后面,这样就可以保持原有的前后顺序不变,所以插入排序是稳定的排序算法。

 

标签:arr,int,复杂度,插入,算法,排序,插入排序
From: https://www.cnblogs.com/luwei0424/p/17742850.html

相关文章

  • 【基础算法】排序算法 —— 选择排序
    一、算法原理选择排序将数组分为已排序区间和未排序区间,每次选择未排序区间的最小元素,将它放到已排序区间末尾。一次选择会让一个元素移动到它应该在的位置,重复n次,就完成了n个数据的排序。 示例:使用选择排序对数组arr=[4,5,6,3,2,1]从小到大排序。第1次选择:第2次选择:......
  • 【基础算法】排序算法 —— 冒泡排序
    一、算法原理冒泡排序只会操作相邻的两个数据。每次冒泡操作都会对相邻的两个元素进行比较,如果不满足大小关系要求,就进行交换。一次冒泡会让至少一个元素移动到它应该在的位置,重复n次,就完成了n个数据的排序。 示例:使用冒泡排序对数组arr=[4,5,6,3,2,1]从小到大排序。第1次......
  • 稳定婚姻问题(Gale-Shapley算法)
    前言今天duck、香饽饽老板和彬彬一起出了个模拟赛,赛时T2想到了跟正解很接近的做法,但最后还是打挂了then喜提0pts,后面duck讲题的时候才知道是稳定婚姻板题。看完证明之后觉得很妙,遂开坑。只是简单整理,图一乐子吧算是。说是稳定婚姻问题,但其实我觉得更合适的叫法是属性稳定分......
  • 【基础算法】排序算法
    一、排序算法简介排序是对批量数据按照一定的顺序进行排列的操作。1.1学习排序算法的要点算法原理、代码实现、评价算法优劣。1.2评价排序算法的优劣排序算法的优劣可以从以下3个方面进行评价:时间性能:最好、最坏、平均时间复杂度;内存占用:是否原地排序,原地排序算法,......
  • eslint airbnb React18+typescript 依赖循环、import自动排序分组
    eslint终极规范爱彼迎eslint-config-airbnb请先阅读完下以下链接在来配置代码规范之什么是eslint,为什么要使用eslinteslint的配置项过多,针对js、ts、vue、jsx、tsx等等不同的规则,小公司或者个人项目可以使用成熟的eslint社区规范,如airbnb、standard、goole等。这里我们介绍......
  • C/C++学习 -- 分组加密算法(DES算法)
    数据加密标准(DataEncryptionStandard,DES)是一种对称密钥加密算法,是信息安全领域的经典之作。本文将深入探讨DES算法的概述、特点、原理,以及提供C语言和C++语言实现DES算法的代码案例。一、DES算法概述DES算法是一种对称密钥加密算法,由IBM于1977年开发并于1977年被美国国家标准局(NI......
  • 02 快速排序(快排)
    #include"stdio.h"voidQuickSort(int*array,intlow,intheight){inti,j,tmp;//两个哨兵,和开头的元素下标inttemp;i=low;j=height;tmp=array[low];if(i>j)//如果下标i大于下标j,函数结束运行{return;}......
  • 视频融合/监控汇聚平台EasyCVR人形检测算法应用汇总
    安防视频监控平台EasyCVR是一个具有强大拓展性、灵活的视频能力和轻便部署的平台。它支持多种主流标准协议,包括国标GB28181、RTSP/Onvif、RTMP等,还可以支持厂家的私有协议和SDK接入,例如海康Ehome、海大宇等设备的SDK。该平台不仅拥有传统安防视频监控的功能,还具备接入AI智能分析的......
  • 排序算法
    在线验证算法排序数组算法实现1.快排思路树的前序遍历。每次选取一个数作基准值,将小于基准值的数放在左边,大于基准值的数放在右边。遍历左子树及右子树,直到只有1个数为止。实现classQuickSort{publicstaticvoidsort(int[]nums){shuffle(nums);......
  • 归并排序算法详解
    算法介绍引用百度百科的介绍。归并排序(MergeSort)是建立在归并操作上的一种有效,稳定的排序算法,该算法是采用分治法(DivideandConquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表......