插入排序算法

简介: 插入排序算法是一种简单直观的排序方法,通过将每个元素插入到已排序序列中的合适位置,最终完成整个序列的排序。其时间复杂度为 O(n²),适用于小规模数据的排序。

插入排序算法可以对指定序列完成升序(从小到大)或者降序(从大到小)排序,对应的时间复杂度O(n2)


插入排序算法的实现思路是:初始状态下,将待排序序列中的第一个元素看作是有序的子序列。从第二个元素开始,在不破坏子序列有序的前提下,将后续的每个元素插入到子序列中的适当位置。


举个简单的例子,用插入排序算法对 {14, 33, 27, 10, 35, 19, 42, 44} 实现升序排序的过程如下:


1) 将第一个元素 14 看作是一个有序的子序列 {14},将剩余元素逐个插入到此序列的适当位置:



2) 将 33 插入到 {14} 中,由于 33 > 14,所以 33 应该插入到 14 的后面,新的有序序列变为 {14, 33};



3) 将 27 插入到 {14, 33} 中,由于 27 < 33 同时 27 > 14,所以 27 应该插入到 14 和 33 的中间,新的有序序列变为 {14, 27, 33};



4) 将 10 插入到 {14, 27, 33} 中,经过依次和 33、27、14 比较,最终断定 10 应该插入到 14 之前,新的有序序列变为 {10, 14, 27, 33};



5) 将 35 插入到 {10, 14, 27, 33} 中,由于 35 > 33,所以 35 应该插入到 33 之后,新的有序序列变为 {10, 14, 27, 33, 35};



6) 将 19 插入到 {10, 14, 27, 33, 35} 中,经过依次和 35、33、27、14 比较,最终断定 19 应该插入到 14 和 27 之间,新的有序序列变为 {10, 14, 19, 27, 33, 35};



7) 将 42 插入到 {10, 14, 19, 27, 33, 35} 中,由于 42 > 35,所以 42 应插入到 35 之后,新的有序序列变为 {10, 14, 19, 27, 33, 35, 42};



8) 将 44 插入到 {10, 14, 19, 27, 33, 35, 42} 中,由于 44 > 42,所以 44 应插入到 42 之后,新的有序序列变为 {10, 14, 19, 27, 33, 35, 42, 44}。



经过将各个待排序的元素插入到有序序列的适当位置,最终得到的就是一个包含所有元素的有序序列。

插入排序算法的具体实现

实现插入排序算法的伪代码如下:

// list 为待排序序列

insertion_sort(list):

   // 从第 2 个元素开始遍历序列

   for i <- 2 to length(list):

       //记录要插入的目标元素

       insert_elem = list[i]

       //记录目标元素所在的位置

       position = i

       //从 position 所在位置向前遍历,直至找到一个比目标元素小的元素,目标元素插入到该元素之后的位置

       while position > 0 and list[position-1] > insert_elem:      // 此为升序排序,实现降序排序改为 list[position-1] < insert_elem

           //移动前一个元素的位置,将其向后移动一个位置

           list[position] = list[position-1]

           position = position - 1

       if(position != i):

           list[position] = insert_elem

   return list


结合伪代码,如下是用插入排序算法对 {14, 33, 27, 10, 35, 19, 42, 44} 实现升序排序的C语言程序:

  1. #include <stdio.h>
  2. #define MAX 8   //设定待排序序列中的元素个数
  3. //list[MAX]为待排序序列
  4. void insertion_sort(int list[MAX]) {
  5. int insert_elem;
  6. int position;
  7. int i;

  8. //从第 2 个元素(下标为 1)开始遍历
  9. for (i = 1; i < MAX; i++) {
  10. // 记录要插入的目标元素
  11.        insert_elem = list[i];
  12. // 记录目标元素所在的位置,从此位置向前开始遍历
  13.        position = i;

  14. // 从 position 向前遍历,找到目标元素的插入位置
  15. while (position > 0 && list[position - 1] > insert_elem) {
  16. //position 处的元素向后移动一个位置
  17.            list[position] = list[position - 1];
  18.            position--;
  19. }
  20. //将目标元素插入到指定的位置
  21. if (position != i) {
  22.            list[position] = insert_elem;
  23. }
  24. }
  25. }

  26. int main() {
  27. int i;
  28. int list[MAX] = { 14, 33, 27, 10, 35, 19, 42, 44 };
  29. insertion_sort(list);
  30. //输出 list 数组中已排好序的序列
  31. for (i = 0; i < MAX; i++) {
  32. printf("%d ", list[i]);
  33. }
  34. }


如下是用插入排序算法对 {14, 33, 27, 10, 35, 19, 42, 44} 实现升序排序的 Java 程序:

  1. public class Demo {
  2. public static void insertion_sort(int[] list) {
  3. int length = list.length;
  4. // 从第 2 个元素(下标为 1)开始遍历
  5. for (int i = 1; i < length; i++) {
  6. // 记录要插入的目标元素
  7. int insert_elem = list[i];
  8. // 记录目标元素所在的位置,从此位置向前开始遍历
  9. int position = i;
  10. // 从 position 向前遍历,找到目标元素的插入位置
  11. while (position > 0 && list[position - 1] > insert_elem) {
  12. // position 处的元素向后移动一个位置
  13.                list[position] = list[position - 1];
  14.                position--;
  15. }
  16. // 将目标元素插入到指定的位置
  17. if (position != i) {
  18.                list[position] = insert_elem;
  19. }
  20. }
  21. }

  22. public static void main(String[] args) {
  23. int[] list = { 10, 14, 19, 27, 33, 35, 42, 44 };
  24. insertion_sort(list);
  25. // 输出已排好序的序列
  26. for (int i = 0; i < list.length; i++) {
  27.            System.out.print(list[i] + " ");
  28. }
  29. }
  30. }


如下是用插入排序算法对 {14, 33, 27, 10, 35, 19, 42, 44} 实现升序排序的 Python 程序:

  1. #待排序序列
  2. list = [10, 14, 19, 27, 33, 35, 42, 44]
  3. def insertion_sort():
  4.    length = len(list)
  5. # 从第 2 个元素(下标为 1)开始遍历
  6. for i in range(1,length):
  7. # 记录要插入的目标元素
  8.        insert_elem = list[i];
  9. # 记录目标元素所在的位置,从此位置向前开始遍历
  10.        position = i
  11. # 从 position 向前遍历,找到目标元素的插入位置
  12. while position > i and list[position - 1] > insert_elem:
  13. # position 处的元素向后移动一个位置
  14.            list[position] = list[position - 1]
  15.            position = position - 1
  16. # 将目标元素插入到指定的位置
  17. if position != i:
  18.            list[position] = insert_elem

  19. insertion_sort()
  20. # 输出已排好序的序列
  21. for i in list:
  22. print(i,end=" ")


以上程序的输出结果均为:

10 14 19 27 33 35 42 44

相关文章
|
1月前
|
算法 Java C语言
弗洛伊德算法求最短路径
弗洛伊德算法用于寻找加权图中各顶点间的最短路径,适用于无向图和有向图。算法基于动态规划思想,通过枚举中间顶点来更新路径,确保最终得到最短路径。该算法要求路径权值非负,否则可能出错。
105 0
|
1月前
|
人工智能 调度 数据安全/隐私保护
. Stable Diffusion 的工作流程(底层原理)
本文介绍了 Stable Diffusion 文生图模型的工作流程,包括输入文本描述、语义编码、图像生成与解码等关键步骤,揭示了 AI 如何将文字转化为图像的技术原理。
161 0
|
1月前
|
文字识别 算法 语音技术
基于模型蒸馏的大模型文案生成最佳实践
本文介绍了基于模型蒸馏技术优化大语言模型在文案生成中的应用。针对大模型资源消耗高、部署困难的问题,采用EasyDistill算法框架与PAI产品,通过SFT和DPO算法将知识从大型教师模型迁移至轻量级学生模型,在保证生成质量的同时显著降低计算成本。内容涵盖教师模型部署、训练数据构建及学生模型蒸馏优化全过程,助力企业在资源受限场景下实现高效文案生成,提升用户体验与业务增长。
327 23
|
1月前
|
存储 算法
最小生成树的概念与思想
数据结构中的图存储结构包含顶点和边,分为连通图与非连通图。生成树是包含所有顶点、任意两点间仅有一条通路的极小连通图。最小生成树则是权值总和最小的生成树,常用于解决道路建设等实际问题,常用算法有普里姆算法和克鲁斯卡尔算法。
43 0
|
1月前
|
算法 Java C语言
汉诺塔问题
汉诺塔问题源自印度古老传说,涉及将一组圆盘从一根柱子移动到另一根,遵循特定规则。文章详细介绍了该问题的背景、解决思路以及如何使用分治算法实现,同时提供了C语言、Java和Python的代码示例。
128 0
|
1月前
|
算法
回溯算法的基本思想
本节介绍回溯算法,通过图1中从A到K的路径查找示例,说明其与穷举法的异同。回溯算法通过“回退”机制高效试探各种路径,适用于决策、优化和枚举问题。
43 0
|
1月前
|
人工智能 缓存 JavaScript
Function AI 助力用户自主开发 MCP 服务,一键上云高效部署
在 AI 与云原生融合的趋势下,开发者面临模型协同与云端扩展的挑战。MCP(模型上下文协议)提供统一的交互规范,简化模型集成与服务开发。Function AI 支持 MCP 代码一键上云,提供绑定代码仓库、OSS 上传、本地交付物部署及镜像部署等多种构建方式,助力开发者高效部署智能服务,实现快速迭代与云端协同。
274 22
|
1月前
|
SQL JSON 监控
JSON 日志分析的“正确姿势”:阿里云 SLS 高效实践指南
JSON 日志因灵活易扩展而广泛应用,但其海量数据也带来分析挑战。本文系统介绍阿里云日志服务(SLS)中处理 JSON 日志的最佳实践,涵盖数据预处理、索引配置、JSON 函数使用及 SQL 智能生成,助你高效挖掘日志价值。
314 23
|
1月前
|
XML Java Maven
@Bean`注解的使用方法及其作用
本文介绍了Spring框架中`@Bean`注解的使用方法及其作用,包括如何将第三方类库加入Spring容器,配置类与`@Configuration`的配合使用,以及通过`@ConditionalOnClass`、`@ConditionalOnMissingBean`等条件注解控制Bean的加载。同时讲解了Maven父子模块间的依赖关系及配置方式,帮助开发者更好地管理项目结构与依赖注入。
|
2月前
|
JavaScript 前端开发
for of和 for in的区别
JavaScript中,for...of遍历可迭代对象的值,适合数组;for...in遍历对象属性,注意其遍历顺序不确定且包括继承属性,可用hasOwnProperty判断自身属性。同步指任务依次执行,异步则通过回调或事件实现非阻塞执行,适用于耗时任务如网络请求。常见异步方式包括定时器、接口调用、事件监听。
139 0