数据结构和算法之插入排序

一、插入排序

插入排序是一种简单直观的排序算法。它的原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。
有元素 无元素 无元素 初始数组 未排序区间 选择一个待插入元素 已排序区间 插入元素到已排序区间 重新确定未排序区间 排序完成

这个流程图描述了插入排序的过程。初始数组经过选择一个待插入元素的步骤,并判断是否有元素。如果有元素,则将它插入到已排序区间,并重新确定未排序区间。如果没有元素,则排序完成。

js实现:

javascript 复制代码
function insertionSort(arr) {
   // 循环每个元素,从第二个元素开始
   for (let i = 1; i < arr.length; i++) {
      // 当前元素
      let current = arr[i];
      // 设置当前元素的前一个元素的下标
      let j = i - 1;

      // 当前元素与它前面的元素比较,如果前面的元素较大,则向右移动
      while (j >= 0 && arr[j] > current) {
         arr[j + 1] = arr[j];
         j--;
      }

      // 将当前元素插入到正确的位置
      arr[j + 1] = current;
   }

   // 返回排序后的数组
   return arr;
}

let array = [5, 3, 8, 2, 1, 4];
console.log(insertionSort(array));  // 输出:[1, 2, 3, 4, 5, 8]

这里使用插入排序算法对数组 [5, 3, 8, 2, 1, 4] 进行排序。首先,第一个元素 5 被标记为已排序序列,从第二个元素开始,依次与已排序序列中的元素比较,找到合适的位置插入。在每一轮循环中,当前元素会与已排序序列中的元素从后向前依次比较,直到找到插入位置。

初始数组:8, 3, 5, 1, 4

插入元素 过程描述 排序后的数组
8 初始状态 8, 3, 5, 1, 4
3 将3插入到前面比它大的数之前 3, 8, 5, 1, 4
5 将5插入到前面比它大的数之前 3, 5, 8, 1, 4
1 将1插入到前面比它大的数之前 1, 3, 5, 8, 4
4 将4插入到前面比它大的数之前 1, 3, 4, 5, 8

最终排序结果:1, 3, 4, 5, 8

插入排序的过程可以类比现实生活中整理扑克牌的过程。初始时,我们手里有一摞乱序的扑克牌。我们从第二张牌开始,将其与前面的牌依次比较,找到合适的位置插入。重复这个过程,直到所有的牌都被按照顺序放置在手上。每次比较时,左手持有的牌都是已排序的,右手持有的牌都是未排序的。这个过程就是插入排序的模拟。

二、使用二分法优化插入排序

可以使用二分法优化上述插入排序算法。二分法优化的思想是将插入排序中的线性查找部分改为二分查找,从而减少比较的次数,提高排序效率。

以下是使用二分法优化的插入排序算法:

javascript 复制代码
function insertionSort(arr) {
   for (let i = 1; i < arr.length; i++) {
      let current = arr[i];
      let left = 0; // 排序部分的起始位置
      let right = i - 1; // 排序部分的结束位置

      // 使用二分查找找到插入位置
      while (left <= right) {
         let mid = Math.floor((left + right) / 2);
         if (arr[mid] > current) {
            right = mid - 1;
         } else {
            left = mid + 1;
         }
      }

      // 将大于current的元素右移
      for (let j = i - 1; j >= left; j--) {
         arr[j + 1] = arr[j];
      }

      // 插入到正确的位置
      arr[left] = current;
   }

   return arr;
}

使用二分法优化后,排序效率会有所提高,但在数据量较小时可能没有明显的优势。因此,在实际应用中需要根据具体情况选择是否使用二分法优化。

相关推荐
Zldaisy3d5 分钟前
全球唯一仿真驱动自适应扫描路径新版本发布,金属3D打印工艺开发进入算法时代
算法·3d
小江的记录本9 分钟前
【JVM虚拟机】类加载机制:类加载全流程:加载→验证→准备→解析→初始化(附《思维导图》+《面试高频考点清单》)
java·jvm·spring boot·算法·安全·spring·面试
故事和你9142 分钟前
洛谷-【动态规划2】线性状态动态规划4
开发语言·数据结构·c++·算法·动态规划·图论
Larcher43 分钟前
JS 变量提升:代码没动,为什么执行顺序就变了?
前端·javascript·前端框架
yingyima44 分钟前
MySQL 事件调度器速查:核心语法与实战代码
前端
GISer_Jing44 分钟前
Claude Code多Agent架构深度剖析
前端·人工智能·架构·自动化
comphub1 小时前
comp-hub:让你的 Vue 业务组件真正"活"起来
前端
不吃土豆的马铃薯1 小时前
Socket 网络编程实战教程
linux·服务器·开发语言·网络·c++·算法
AI砖家1 小时前
Claude Code 跳过确认完全指南:让 AI 自己完成开发任务
前端·人工智能·python·ai编程·代码规范
KaMeidebaby1 小时前
卡梅德生物技术快报|Pull Down 实验在 lncRNA - 蛋白互作机制研究中的应用实例解析
大数据·前端·架构·spark·新浪微博