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

算法-插入排序

插入排序算法概述

插入排序的原理是构建有序序列,对于给定的一个无序序列,从前往后遍历,在该元素之前的序列中从后往前扫描,寻找正确位置,这样对于每一个正在排序的元素,前面的序列总是有序的,当遍历完整个序列,即完成排序。《算法导论》给了一个更通俗更容易理解的形象的描述。我们都玩过扑克牌,大多数人拿扑克牌的时候都有这么个习惯,那就是将扑克牌按照一定的顺序排列好,而插入排序就好比你不断从桌上一堆无序排中拿起最上面的那张,然后放入自己手中已有的牌中,而每一次放的过程你都会按照某个顺序将这张新拿到的牌插入正确的位置,这样你手中的牌一直是有序的,而你抽取牌所在的牌堆是无序的。

算法描述

下面以非降序排序为例:

  1. 从第一个元素开始,该元素视为已经被排序;
  2. 取出下一个元素记为key,在前面已排序的有序序列中从后往前扫描;
  3. 如果扫描过程中的元素大于key,将该元素移至下一个位置;
  4. 重复3,直至找到已排序的元素小于或等于key的位置;
  5. key插入到该位置;
  6. 重复2-5,直到整个序列遍历完即得到一个原地排序好的序列。

执行过程图解

以斜体数字如 (1) 表示key,以粗体数字如 ‘1’ 表示已排序序列,为了更直观,用中括号括起来,普通数字如‘1’表示未排序乱序序列,简要表示排序流程如下:

  • 5 2 4 6 1 3
  • [5] (2) 4 6 1 3
  • [2 5] (4) 6 1 3
  • [2 4 5] (6) 1 3
  • [2 4 5 6] (1) 3
  • [1 2 4 5 6] (3)
  • [1 2 3 4 5 6]

可以在这里看到插入排序的动态演示:
VisuAlgo-排序(冒泡排序,选择排序,插入排序,归并排序,快速排序,基数排序,基数排序)

插入排序伪代码

(伪代码引用《算法导论》给出的例子)
INSERTION-SORT(A)

for j = 2 to A.length
  key = A[j]
  // Insert A[j] into the sorted sequence A[1..j - 1].
  i = j - 1
  while i > 0 and A[i] > key
    A[i + 1] = A[i]
    i = i - 1
  A[i + 1] = key

插入排序实现

为了更直观,我们将所有元素从1号元素开始计数,将0号元素视为无穷小,即数组长度为arrLength + 1,序列存储于arr[1..arrLength]

C

void insertionSort(arrType* arr, int arrLength)
{
  int i, j;
  arrType key;

  for (j = 2; j <= arrLength; j++) {
    key = arr[j];

    i = j - 1;
    while (i > 0 && arr[i] > key) {
      arr[i + 1] = arr[i];
      i--;
    }
    arr[i + 1] = key;
  }
}

Pascal

procedure insertsort;   
var
  i,j,key:integer;
begin
  arr[0] := -maxint;
  for j := 2 to n do
  begin
    i := j - 1;
    key := arr[j];
    while arr[i] > key do
    begin
      arr[i + 1] := arr[i];
      i := i - 1;
    end;
    arr[i + 1] := key;
  end;
end;  

参考资料

  • 《算法导论》(原书第3版)
  • 插入排序-维基百科,自由的百科全书
  • 《Free Pascal 语言与基础算法》

相关文章:

  • HAWQ配置之客户端访问
  • 自动化测试Jest及其应用
  • 前端h5框架总结
  • Linux基础命令---sudo
  • Algs4-1.1.11编写一段代码,打印出一个二维布尔数组的内容
  • [Google Guava] 2.1-不可变集合
  • I/O复用模型详解(网络总结)
  • [ARC066F]Contest with Drinks Hard
  • 5.0中redis-cli的集群管理测试
  • linux基础学习【10】
  • 北京博派通达科技有限公司(前端面试题) 给需要的人
  • IT界提问的艺术
  • hadoop生态搭建(3节点)-15.Nginx_Keepalived_Tomcat配置
  • Hadoop在安装snappy过程中的问题
  • localStorage和sessionStorage
  • 【翻译】Mashape是如何管理15000个API和微服务的(三)
  • Android 初级面试者拾遗(前台界面篇)之 Activity 和 Fragment
  • DOM的那些事
  • Java 23种设计模式 之单例模式 7种实现方式
  • Node + FFmpeg 实现Canvas动画导出视频
  • PHP 程序员也能做的 Java 开发 30分钟使用 netty 轻松打造一个高性能 websocket 服务...
  • PyCharm搭建GO开发环境(GO语言学习第1课)
  • sessionStorage和localStorage
  • 后端_ThinkPHP5
  • 前端相关框架总和
  • 微信小程序:实现悬浮返回和分享按钮
  • 小程序button引导用户授权
  • 协程
  • Semaphore
  • 仓管云——企业云erp功能有哪些?
  • 通过调用文摘列表API获取文摘
  • 曜石科技宣布获得千万级天使轮投资,全方面布局电竞产业链 ...
  • (2)STL算法之元素计数
  • (2020)Java后端开发----(面试题和笔试题)
  • (bean配置类的注解开发)学习Spring的第十三天
  • (ctrl.obj) : error LNK2038: 检测到“RuntimeLibrary”的不匹配项: 值“MDd_DynamicDebug”不匹配值“
  • (Python) SOAP Web Service (HTTP POST)
  • (附源码)spring boot建达集团公司平台 毕业设计 141538
  • (附源码)ssm高校升本考试管理系统 毕业设计 201631
  • (六)c52学习之旅-独立按键
  • (强烈推荐)移动端音视频从零到上手(上)
  • (一)UDP基本编程步骤
  • .NET Micro Framework 4.2 beta 源码探析
  • .NET/C# 解压 Zip 文件时出现异常:System.IO.InvalidDataException: 找不到中央目录结尾记录。
  • .net图片验证码生成、点击刷新及验证输入是否正确
  • /etc/skel 目录作用
  • @GlobalLock注解作用与原理解析
  • [acwing周赛复盘] 第 94 场周赛20230311
  • [Angular 基础] - 表单:响应式表单
  • [BT]BUUCTF刷题第9天(3.27)
  • [C#]winform部署yolov5-onnx模型
  • [C++数据结构](22)哈希表与unordered_set,unordered_map实现
  • [CentOs7]iptables防火墙安装与设置
  • [flume$2]记录一个写自定义Flume拦截器遇到的错误
  • [HackMyVM]靶场Crossbow