插入排序算法

简介: 插入排序算法是一种简单直观的排序方法,通过将每个元素插入到已排序序列中的合适位置,最终完成整个序列的排序。其时间复杂度为 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

相关文章
|
安全
C 标准库 - <signal.h> 详解
`&lt;signal.h&gt;` 是 C 标准库中的头文件,提供信号处理功能,用于通知程序特定事件,如非法操作或定时器到期。它定义了多种信号常量(如 `SIGINT`、`SIGTERM`、`SIGKILL`、`SIGSEGV`、`SIGUSR1` 和 `SIGUSR2`),并允许通过 `signal()` 或 `sigaction()` 设置信号处理函数。
|
9月前
|
搜索推荐 算法
桶排序算法
桶排序是一种高效的排序算法,基于分治思想,理想时间复杂度为O(n)。它通过将数据分到多个桶中,每个桶再单独排序,最后按序合并各桶元素,从而实现整体有序。
631 0
|
消息中间件 XML 网络协议
『NLog』.Net使用NLog使用方式及详细配置(输出至文件/RabbitMQ/远程网络Tcp)
📣读完这篇文章里你能收获到 - Nlog输出至文件/RabbitMQ/远程网络Tcp配置文档 - Nlog配置参数详解 - .NET CORE项目接入
6709 0
『NLog』.Net使用NLog使用方式及详细配置(输出至文件/RabbitMQ/远程网络Tcp)
|
9月前
|
算法 Java C语言
弗洛伊德算法求最短路径
弗洛伊德算法用于寻找加权图中各顶点间的最短路径,适用于无向图和有向图。算法基于动态规划思想,通过枚举中间顶点来更新路径,确保最终得到最短路径。该算法要求路径权值非负,否则可能出错。
734 0
|
9月前
|
算法 程序员
时间复杂度和空间复杂度的概念
本文介绍了如何评估算法的执行效率和内存占用,重点讲解了时间复杂度和空间复杂度的概念及其计算方法。通过大O记法,可以量化算法的运行时间和内存使用情况,从而在不同算法间做出合理选择。
373 0
|
9月前
|
算法
回溯算法的基本思想
本节介绍回溯算法,通过图1中从A到K的路径查找示例,说明其与穷举法的异同。回溯算法通过“回退”机制高效试探各种路径,适用于决策、优化和枚举问题。
251 0
|
9月前
|
算法 Java 定位技术
迷宫问题
迷宫问题是指在给定区域内寻找从起点到终点的可行路径。可以使用回溯算法解决,通过不断尝试四个方向(上下左右)移动,若无法前进则回退,直到找到终点或遍历所有可能路径。文中还给出了C语言、Java和Python的实现代码,并展示了运行结果。
347 0
|
9月前
|
算法 Java C语言
汉诺塔问题
汉诺塔问题源自印度古老传说,涉及将一组圆盘从一根柱子移动到另一根,遵循特定规则。文章详细介绍了该问题的背景、解决思路以及如何使用分治算法实现,同时提供了C语言、Java和Python的代码示例。
641 0
|
9月前
|
存储 搜索推荐 算法
归并排序算法
归并排序是一种基于分治思想的高效排序算法,通过将序列不断划分为不可再分的子序列,再两两合并完成排序。其时间复杂度为O(nlogn),适用于对序列进行升序或降序排列。
496 0