当前位置: 首页 > news >正文

直接插入排序(C语言实现)

目录

1.直接插入排序介绍

2.实现思路

3.动图展示

4.代码实现 (升序)

单趟排序实现

单趟排序代码

直接插入排序函数

5.代码测试

6.时空复杂度分析

 时间复杂度O(N^2)

 空间复杂度O(1)


1.直接插入排序介绍

插入排序,又叫直接插入排序。实际中,我们玩扑克牌的时候,就用了插入排序的思想。
基本思想:
 在待排序的元素中,假设前n-1个元素已有序,现将第n个元素插入到前面已经排好的序列中,使得前n个元素有序。按照此法对所有元素进行插入,直到整个序列有序。

 但我们并不能确定待排元素中究竟哪一部分是有序的,所以我们一开始只能认为第一个元素是有序的,依次将其后面的元素插入到这个有序序列中来,直到整个序列有序为止。

 2.实现思路

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

 

3.动图展示

4.代码实现 (升序)

单趟排序实现

这里end之前的数字默认已经排序完成

当插入数字大于前面数字,我们这。里采用极端情况,大于前面所有数字时

那么我们需要吧end 之前的数字往后移,end一直往前移,当end减到-1时,循环停止,tmp放到end+1的位置上。

如果只是大于前面部分代码,当end走到a[end]<tmp时,直接跳出循环,将a[end+1] = tmp;

单趟排序代码

void InsertSort(int* a, int n)
{int end;int tmp = a[end + 1];while (end >= 0){if (tmp < a[end]){a[end + 1] = a[end];end--;}else{break;}}a[end + 1] = tmp;
}

 这里只有当找到插入位置,和循环走完才会截止循环。

 直接插入排序函数

这里我们让end从0开始,一个元素即是有序数组。i<n-1即可。小于n时会越界访问,tmp = a[end+1],i走到n-2时就已经让最后一个数进行插入排序了。

void InsertSort(int* a, int n)
{for (int i = 0; i < n-1; i++){int end = i;int tmp = a[end + 1];while (end >= 0){if (tmp < a[end]){a[end + 1] = a[end];end--;}else{break;}}a[end + 1] = tmp;}
}

5.代码测试

void TestInsertSort()
{int a[] = { 66,11,22,55,47,21,98,31,26,78 };printf("插入前\n");Print(a, sizeof(a) / sizeof(a[0]));printf("插入后\n");InsertSort(a, sizeof(a) / sizeof(a[0]));Print(a, sizeof(a) / sizeof(a[0]));
}int main()
{TestInsertSort();}

 

6.时空复杂度分析

 时间复杂度O(N^2)

最坏情况 :如果数组是完全逆序的,那么每次插入操作都需要将元素移到已排序部分的开头。这就意味着对于第i个元素,可能需要进行i次比较和移动。这种情况下,算法的时间复杂度是O(N^2),因为需要进行总计约1 + 2 + 3 + … + (n-1)次比较,这是一个n(n-1)/2的等差数列

最好情况 :这种情况发生在数组已经完全有序时。在这种情况下,每次比较后,很快就会找到插入位置(在已排序元素的末尾),不需要进行额外的移动。因此,最好情况下插入排序的时间复杂度是O(N),因为外层循环只会遍历一次数组,内层循环不会进行任何实际的比较和移动操作。

空间复杂度O(1)

 插入排序的空间复杂度为O(1),因为它是一个原地排序算法,不需要额外的存储空间来排序

插入排序特性总结

1. 元素集合越接近有序,直接插入排序算法的时间效率越高。
2. 时间复杂度:O(N^2)。
3. 空间复杂度:O(1),它是一种稳定的排序算法。
4. 稳定性:稳定。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • Spring 源码解读:手动实现Spring事件机制
  • 深入解析:HTTP 和 HTTPS 的区别
  • 2024年数学建模比赛题目及解题代码
  • Xv6异常处理(二):内核异常
  • 练习题 - Django 4.x Models Meta 元数据选项
  • 电竞显示器哪个牌子好
  • DNS攻击频发,打造防劫持DNS需强化“数据治理”理念
  • 探索Facebook的黑暗面:数字化社交的双面剑
  • 了解Node开发基础知识
  • Python--TCP/UDP通信
  • 使用gitee如何回滚上一个版本,简单操作方式-gitee自带功能无需使用代码
  • P9235 [蓝桥杯 2023 省 A] 网络稳定性
  • 【动态规划】下降路径最小和 C++
  • 互联网全景消息(5)之RocketMq快速入门(下)
  • DHCP协议原理(网络协议)
  • 【Linux系统编程】快速查找errno错误码信息
  • 4. 路由到控制器 - Laravel从零开始教程
  • leetcode-27. Remove Element
  • Storybook 5.0正式发布:有史以来变化最大的版本\n
  • 诡异!React stopPropagation失灵
  • 技术:超级实用的电脑小技巧
  • 模型微调
  • 嵌入式文件系统
  • 如何设计一个微型分布式架构?
  • 王永庆:技术创新改变教育未来
  • RDS-Mysql 物理备份恢复到本地数据库上
  • 微龛半导体获数千万Pre-A轮融资,投资方为国中创投 ...
  • ​​​​​​​开发面试“八股文”:助力还是阻力?
  • # 睡眠3秒_床上这样睡觉的人,睡眠质量多半不好
  • # 详解 JS 中的事件循环、宏/微任务、Primise对象、定时器函数,以及其在工作中的应用和注意事项
  • #pragma once
  • #大学#套接字
  • #如何使用 Qt 5.6 在 Android 上启用 NFC
  • $.proxy和$.extend
  • (+4)2.2UML建模图
  • (26)4.7 字符函数和字符串函数
  • (C11) 泛型表达式
  • (c语言+数据结构链表)项目:贪吃蛇
  • (Redis使用系列) SpirngBoot中关于Redis的值的各种方式的存储与取出 三
  • (Redis使用系列) Springboot 整合Redisson 实现分布式锁 七
  • (二)PySpark3:SparkSQL编程
  • (附源码)ssm教师工作量核算统计系统 毕业设计 162307
  • (四) Graphivz 颜色选择
  • (四)linux文件内容查看
  • (一)Linux+Windows下安装ffmpeg
  • (转)母版页和相对路径
  • (转载)深入super,看Python如何解决钻石继承难题
  • .net CHARTING图表控件下载地址
  • .Net IOC框架入门之一 Unity
  • .NET 反射的使用
  • .NET 分布式技术比较
  • .net的socket示例
  • .NET命令行(CLI)常用命令
  • 。Net下Windows服务程序开发疑惑
  • /*在DataTable中更新、删除数据*/