排序算法——直接插入排序

news/2025/2/21 8:38:03/

直接插入排序

基本思想

  • 直接插入排序是一种简单明了的插入排序法,其基本思想是:把待排序的数据按其关键码值的大小逐个插入到一个已经排好序的有序序列中,直到所有数据插入完为止。

  • 在现实生活中,我们玩扑克对牌进行排序就运用了这种思想。

    在这里插入图片描述

整体插入思想

统一使用升序

  • 当插入第(i >= 1)个元素时,前面的array[0], array[1], ……, array[i - 1]已经有序,此时用array[i]的值与array[i - 1], array[i - 2],……的值顺序进行比较,找到插入位置即将array[i]插入,原来位置上的元素顺序后移。

  • 如对数组{2, 5, 4, 6, 8, 7, 1}进行升序排序

    在这里插入图片描述

代码实现

  • 我们假设数组中[0,end]的数据已经有序,要将nums[end + 1]这个元素插入到[0,end]中,使[0,end + 1]也有序

  • 因为可能要进行数据后移的操作,为防止nums[end + 1]被覆盖而无法得到其值,要事先用临时变量保存

    int end;
    int temp = nums[end + 1];	
    
  • 运用插入排序的思想,将nums[end + 1](即temp)从后往前依次与有序的元素进行比较,满足条件就插入

    while (end >= 0)
    {/*如果后面的数比前面的小,那就将前面的数后移继续将后面的数与更前面的数(即更小的数)比较*/if (temp < nums[end]){nums[end + 1] = nums[end];end--;}/*否则,如果后面的数比前面的大那么满足升序条件,将temp插入到nums[end]的后面*/elsenums[end + 1] = temp;
    }
    
  • 但是,上面这段代码还是存在一个小小的bug,即如果我们要插入的元素temp比有序序列的第一个元素nums[0]还要小,那么执行完 nums[end + 1] = nums[end];end--;这一操作后,end就等于-1了,而循环的条件是end >= 0,无法进入循环,end[0]这一位置也无法被赋值,因此,我们要进行改进:

    while (end >= 0)
    {if (temp < nums[end]){nums[end + 1] = nums[end];end--;}/*如果后面的数比前面的大那么满足升序条件,直接退出循环*/elsebreak;
    }//将(end >= 0 && temp > nums[end])和 (end == -1)这两种情况整合到一起
    nums[end + 1] = temp;
    
  • 设待排序数组有numsSize个元素,因此要使数组有序,就要用一层for循环来分别判断数组的每个值是否处于正确的位置。

    //为防止数组越界,i的最大值为numsSize - 2
    for (int i = 0; i < numsSize - 1; i++)
    {int end = i;int temp = nums[end + 1];…………
    }
    

实现代码

void InsertSort(int* nums, int numsSize)
{//为防止数组越界,i的最大值为numsSize - 2for (int i = 0; i < numsSize - 1; i++){/*假设[0,end]已经有序要将nums[end + 1]这个元素插入到[0,end]中,使[0,end + 1]也有序*/int end = i;int temp = nums[end + 1];	//因为可能要进行数据后移的操作,为防止nums[end + 1]被覆盖而无法得到其值,要事先用临时变量保存	while (end >= 0){if (temp < nums[end]){nums[end + 1] = nums[end];end--;}/*如果后面的数比前面的大那么满足升序条件,直接退出循环*/elsebreak;}//将(end >= 0 && temp > nums[end])和 (end == -1)这两种情况整合到一起nums[end + 1] = temp;}
}

时间复杂度

统一为升序排序

  • 最好的情况:最好的情况就是数组已经升序有序,只有最外面一层for循环遍历一次数组,里面的while循环每一次都是直接退出,因此最好的情况时间复杂度为O(N)
  • 最坏的情况:最坏的情况就是数组是降序排序,里面while循环的时间复杂度为O(N),因此最坏情况下,时间复杂度为O(N2)
  • 综上,直接插入法的时间复杂度为O(N2)

http://www.ppmy.cn/news/183824.html

相关文章

Docker安装Mysql教程(linux)

本文主要讲解如何使用Docker去安装mysql 一、搜索镜像 docker search mysql二、拉取镜像 不指定版本&#xff0c;默认为最新版&#xff0c;这里用的5.7 docker pull mysql:5.7三、创建容器&#xff08;运行镜像&#xff09; 1、内外都使用3306端口&#xff08;确保你的宿主机3…

LeetCode ! 78. subsets

参考资料&#xff1a;leetcode评论区&#xff0c;左程云算法课 78. Subsets Given an integer array nums of unique elements, return all possible subsets (the power set).The solution set must not contain duplicate subsets. Return the solution in any order.Exampl…

华为RH2288V5机型RAID LSI3508 不认插入的盘

该V5机器是当前新款机型&#xff0c;采用2U 双路设计 &#xff0c;最大支持24条服务器型内存DDR4。 支持LSI3108 3508阵列卡。 阵列卡只有在 UEFI引导模式下 才能 进行配置&#xff08;3508亲测&#xff09;。 如果插入新硬盘带阵列信息&#xff0c;开机直接从UEFI引导进入阵列…

【小R记事本】关于Win10更新至21H2版后笔记本电脑WiFi无法使用问题的解决过程

这里写自定义目录标题 计算机型号&#xff1a;Alienware M15X&#xff0c;2017款 问题现象&#xff1a;Win10更新后Wi-Fi无法使用 现象描述&#xff1a; Win10更新后&#xff08;更新至版本号21H2&#xff09;Wi-Fi无法使用&#xff0c;使用网线接入后发现能够使用有线网&#…

【unity之c#】所以迭代器的原理知识你还清楚吗?

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 秩沅 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a;uni…

WIN键失灵

一般就是win键被锁住了&#xff0c;可以用快捷键解锁。 方法一&#xff1a;Fn(F1-F12某个键&#xff0c;根据品牌不同有区别&#xff0c;一个个试过去) 华为 FnF3Cherry FnF9外星人 FnF6… 方法二&#xff1a;FnWin方法三&#xff1a;FnPrtSc&#xff08;ikbc键盘适用&#xf…

如何解决USB数据线连打印机失败问题?

一般的打印机连接电脑时有两种方式&#xff1a;1、USB有线连接 2、同一局域网无线连接。今天就对第一种使用USB连接电脑时无法进行连接遇到的问题&#xff0c;讲解解决办法&#xff1a; 1、端口问题 因为我的电脑是Win7系统&#xff0c;鼠标右键我的电脑&#xff0c;点击管理这…

魅族2更新最新系统无服务器,魅族Flyme7.2稳定版开启内测:重磅功能终于来了,但值得更新吗?...

原标题&#xff1a;魅族Flyme7.2稳定版开启内测&#xff1a;重磅功能终于来了&#xff0c;但值得更新吗&#xff1f; 我是爆侃哥&#xff0c;和你聊聊我想说的科技、互联网趣闻&#xff0c;或许不专业&#xff0c;但希望有所价值 北京时间1月4日&#xff0c;魅族社区&#xff0…