首页 > 编程语言 >详解十大经典排序算法(三):插入排序(Insertion Sort)

详解十大经典排序算法(三):插入排序(Insertion Sort)

时间:2023-12-03 22:01:34浏览次数:40  
标签:Sort arr key int 插入排序 插入 Insertion 排序 复杂度

算法原理

每次从无序部分选择一个元素,将其插入到有序部分的正确位置,重复这个过程直至整个数组有序。

算法描述

插入排序是一种简单直观的排序算法,它的基本思想是将一个待排序的元素插入到已经排序好的序列中的适当位置,从而得到一个新的、长度加一的有序序列。插入排序的过程类似于整理扑克牌的过程。

具体步骤如下:

  1. 从第二个元素开始,将其视为待排序的元素。
  2. 将待排序的元素与已排序的序列从右向左进行比较,直到找到合适的位置。
  3. 将待排序的元素插入到合适的位置,使得插入后的序列仍然有序。
  4. 重复步骤2-3,直到所有元素都被插入到有序序列中。

动画演示

详解十大经典排序算法(三):插入排序(Insertion Sort)_二分查找

代码实现

public static void insertionSort(int[] arr) {
        int n = arr.length;
        for (int i = 1; i < n; i++) {
            int key = arr[i];
            int j = i - 1;
            while (j >= 0 && arr[j] > key) {
                arr[j + 1] = arr[j];
                j--;
            }
            arr[j + 1] = key;
        }
    }

算法复杂度

时间复杂度(最坏)

时间复杂度(最好)

时间复杂度(平均)

空间复杂度

稳定性

O(n^2)

O(n)

O(n^2)

O(1)

稳定

插入排序的优化方式:

  1. 二分查找优化: 在已排序的部分使用二分查找来找到插入位置,而不是逐个比较。这可以减少比较的次数。
public static void binaryInsertionSort(int[] arr) {
        int n = arr.length;

        for (int i = 1; i < n; ++i) {
            int key = arr[i];
            //使用二分查找确定 key 的插入位置 j。这个位置是已排序部分中第一个大于 key 的元素的位置。
            int j = binarySearch(arr, 0, i - 1, key);

            // 移动已排序部分中大于key的元素
            // 比如原数组第一轮:3 1 5 8 2 7 -> 3 3 5 8 2 7,因为 3 > 1,所以把3 复制过去
            System.arraycopy(arr, j, arr, j + 1, i - j);

            // 在合适的位置插入key
            arr[j] = key;
        }
    }

    private static int binarySearch(int[] arr, int low, int high, int key) {
        while (low <= high) {
            int mid = low + (high - low) / 2;

            if (arr[mid] == key) {
                return mid;
            }

            if (arr[mid] < key) {
                low = mid + 1;
            } else {
                high = mid - 1;
            }
        }

        return low;
    }

呜呜呜 二分真是思路很简单,细节是魔鬼。


相关概念

稳定:如果a原本在b前面,而a=b,排序之后a仍然在b的前面。

不稳定:如果a原本在b的前面,而a=b,排序之后 a 可能会出现在 b 的后面。

时间复杂度:对排序数据的总的操作次数。反映当n变化时,操作次数呈现什么规律。

空间复杂度:是指算法在计算机内执行时所需存储空间的度量,它也是数据规模n的函数。

标签:Sort,arr,key,int,插入排序,插入,Insertion,排序,复杂度
From: https://blog.51cto.com/xaye/8669191

相关文章

  • [Codeforces] CF1733C Parity Shuffle Sorting
    题面翻译给定一个长度为\(n\)的数组,你可以对它进行不超过\(n\)次操作。对于每次操作:选择两个下标\(l,r\),满足\(1\leql<r\leqn\);若\(a_l+a_r\)为奇数,将\(a_r\)赋值为\(a_l\),否则将\(a_l\)赋值为\(a_r\)。求一种方案,使得操作后的数组单调不减(即\(a_1\leq......
  • Javascript实现快速排序Quicksort
    "快速排序"的思想很简单,整个排序过程只需要三步:(1)在数据集之中,选择一个元素作为"基准"(pivot)。(2)所有小于"基准"的元素,都移到"基准"的左边;所有大于"基准"的元素,都移到"基准"的右边。(3)对"基准"左边和右边的两个子集,不断重复第一步和第二步,直到所有子集只剩下一个元素为止。代码实现......
  • 详解十大经典排序算法(二):选择排序(Selection Sort)
    算法原理选择排序通过重复选择数组中最小元素,将其与未排序部分的第一个元素交换,实现排序。算法描述选择排序是一种简单的排序算法,它每次从待排序的元素中选择最小(或最大)的元素,将其放到已排序序列的末尾,直到整个序列排序完成。选择排序的基本思想是通过不断选择剩余元素中的最小(或......
  • 折半插入排序
    ACC==1升序,ACC==-1降序#include<stdio.h>#include<stdlib.h>#include<string.h>typedefstruct{intNO;intAge;charName[50];}Student;typedefstruct{intStudentCount;Student*data;}Sqlist;voidBinsersort(Sql......
  • 直接插入排序
    01234528123      从下标1开始遍历,默认第一个元素是已排序序列。例如对元素3进行插入排序:下标0-3分别是2-5-8-12;此时k=arr[4]=3;j=i-1=3;从后往前遍历找到k应该插入的位置当while循环条件 j>=0&&arr[j]>k 一直成立时,arr[j+1]=ar......
  • E. Permutation Sorting
    E.PermutationSortingYouaregivenapermutation$^\dagger$$a$ofsize$n$.Wecallanindex$i$goodif$a_i=i$issatisfied.Aftereachsecond,werotateallindicesthatarenotgoodtotherightbyoneposition.Formally,Let$s_1,s_2,\ldots,s_k$......
  • 微信小程序开发的聚合函数排序.aggregate.sort
    //普通查询用.orderBy('add_time','desc'),聚合查询用.sort({ins_time:-1})'usestrict';constdb=uniCloud.database()//对数据库的对象获取;exports.main=async(event,context)=>{ letstart=newDate().getTime(); constcollection=db......
  • Numpy-argsort()用法和Numpy-flipud()用法
    Numpy-argsort()用法语法:np.argsort(a,axis=-1,kind='quicksort',order=None)功能:对a进行由小到大排序,并输出其索引实例:importnumpyasnptest=np.array([8,2,-2,3,9,1])new_test=np.argsort(test)print('一维数组的排序结果:{}'.format(new_test))输出结......
  • Day20.匿名函数的两种调用方式_max用法_min用法_sorted用法_map用法_filter用法_reduc
    1.匿名函数的两种调用方式: 2.匿名函数求最大和求最小:3.sorted用法和map用法:4.filter的用法:5.reduce的用法:......
  • redis基础命令复习(Sring,Hash,List,Set,SortedSet)
    1,Redis数据结构:  https://redis.io/commands  2,Redis命令---Redis通用命令(常见的有,keys,del,exists,expire,ttl)2.1,keys:查看符合模板的所有key,不建议在生产环境设备上使用 打开redis:win+R,输入cmd,打开命令提示符后,输入redis-server;  再另外打开一个命令提示......