当前位置: 首页 > 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
  • [ JavaScript ] 数据结构与算法 —— 链表
  • 【干货分享】SpringCloud微服务架构分布式组件如何共享session对象
  • 【每日笔记】【Go学习笔记】2019-01-10 codis proxy处理流程
  • 2017-09-12 前端日报
  • es的写入过程
  • HTTP 简介
  • Javascript弹出层-初探
  • Javascript基础之Array数组API
  • Java深入 - 深入理解Java集合
  • PermissionScope Swift4 兼容问题
  • Phpstorm怎样批量删除空行?
  • React-redux的原理以及使用
  • vue-cli在webpack的配置文件探究
  • vue-router 实现分析
  • vue脚手架vue-cli
  • 关于Android中设置闹钟的相对比较完善的解决方案
  • 聚簇索引和非聚簇索引
  • 前端代码风格自动化系列(二)之Commitlint
  • 如何用vue打造一个移动端音乐播放器
  • 如何优雅的使用vue+Dcloud(Hbuild)开发混合app
  • 详解移动APP与web APP的区别
  • 异步
  • 栈实现走出迷宫(C++)
  • 阿里云ACE认证之理解CDN技术
  • ​io --- 处理流的核心工具​
  • ​LeetCode解法汇总1276. 不浪费原料的汉堡制作方案
  • ​云纳万物 · 数皆有言|2021 七牛云战略发布会启幕,邀您赴约
  • # 透过事物看本质的能力怎么培养?
  • #考研#计算机文化知识1(局域网及网络互联)
  • #预处理和函数的对比以及条件编译
  • (12)目标检测_SSD基于pytorch搭建代码
  • (6)设计一个TimeMap
  • (k8s中)docker netty OOM问题记录
  • (pojstep1.1.2)2654(直叙式模拟)
  • (动手学习深度学习)第13章 计算机视觉---微调
  • (附源码)ssm本科教学合格评估管理系统 毕业设计 180916
  • (六)vue-router+UI组件库
  • (转)ORM
  • .[hudsonL@cock.li].mkp勒索病毒数据怎么处理|数据解密恢复
  • .NET/C# 使窗口永不激活(No Activate 永不获得焦点)