JS 这一次彻底理解插入排序
壹 ❀ 引
在前两篇排序文章中,我们分别介绍了冒泡排序与选择排序,趁热打铁,我们接着聊插入排序。老实说,在分析排序过程中头脑很清楚,过后再尝试写出排序代码还有点坎坷...可能是我脑瓜子不太机灵的问题,不过我相信多练习对于算法的感觉会好起来,那么让我们开始。
贰 ❀ 插入排序基本概念
插入排序与我们生活中打扑克牌斗地主的原理相同,在分完手牌后,拿起来就是一堆乱序的牌组,接下来我们总是会一一把排序不对的牌抽出来,并插入到它应该在的位置,那么这个调整牌组顺序的过程就是在做插入排序。只是打扑克时,我们总是会站在宏观视角,以最便捷的方式把牌调整好,而程序不同,它得按照一个逻辑一步步调整,大家明白这个意思就好。

插入排序主要按照如下步骤运转:
- 将数组中的第一个元素看成有序序列,也就是最初的参照点,把从第二个元素到尾部所有元素都看成未排序序列。
- 开始遍历未排序序列,将每个未排序元素插入到有序序列中它应该的位置,如果未排序元素与有序序列中某个元素相同,则将其放到有序序列该元素后面。
我们来看个简单的例子,假设现在有数组[4,2,1,3];
现在4是有序序列,2,1,3为无序序列,开始遍历。
- 无序序列第1次遍历
- 有序序列第1次遍历
- 2与4比较,因为2更小,2与4互换位置,此时有序序列为
2,4,无序序列为1,3。
- 2与4比较,因为2更小,2与4互换位置,此时有序序列为
- 有序序列第1次遍历
- 无序序列第2次遍历
- 有序序列第1次遍历
- 1比4小,互换位置,此时有序序列为
2,1,4,无序序列为3。
- 1比4小,互换位置,此时有序序列为
- 有序序列第2次遍历
- 1比2小,互换位置,此时有序序列为
1,2,4,无序序列为3。
- 1比2小,互换位置,此时有序序列为
- 有序序列第1次遍历
- 无序序列第3次遍历
- 有序序列第1次遍历
- 3比4小,互换位置,此时有序序列为
1,2,3,4,排序完成。
- 3比4小,互换位置,此时有序序列为
- 有序序列第1次遍历
通过上述分析,我们大致可以得到这样几个结论:
- 数组遍历必定是从i=1处开始。
- 每次遍历我们都会拿一个无序序列的元素和有序序列元素进行比较,有序序列可能存在多个,所以需要循环嵌套。
知道了这些,我们来尝试实现代码。
叁 ❀ 插入排序实现
function insertionSort(arr) {
var len = arr.length,
preIndex;
// 无序序列从i=1处开始遍历
for (var i = 1; i < len; i++) {
// 记录上一个值的索引
preIndex = i - 1;
// 如果上一个值比当前值大,互换位置,考虑有序序列可能有多个,所以需要让preIndex递减
while (preIndex >= 0 && arr[preIndex] > arr[preIndex + 1]) {
arr[preIndex] = [arr[preIndex + 1], arr[preIndex + 1] = arr[preIndex]][0];
preIndex--;
};
};
return arr;
};
var arr = [4, 2, 1, 3];
insertionSort(arr); //[1, 2, 3, 4]
当然我这个实现看着可能不太好看,不过我个人感觉更好理解一点,下面是偏官方的插入排序实现:
function insertionSort(arr) {
var len = arr.length;
var preIndex, current;
for (var i = 1; i < len; i++) {
preIndex = i - 1;
current = arr[i];
while (preIndex >= 0 && arr[preIndex] > current) {
arr[preIndex + 1] = arr[preIndex];
preIndex--;
};
arr[preIndex + 1] = current;
};
return arr;
};
与我的实现不同地方在于,它不是每次对比后直接交换位置,而是用当前值一直和上一个比,满足条件就修改当前值,由于preIndex一直递减,所以当前值一直在变,一直比完为止,最后设置数组0项为当前值,而此时的当前值一定是有序序列中最小的一个。比较巧妙,不过从记忆角度上来说,我可能有些记不住....因人而异了。
那么关于插入排序就说到这里,文中如果存在描述不当还望指出,本文结束。
肆 ❀ 参考
JS 这一次彻底理解插入排序的更多相关文章
- 封装常用的js(Base.js)——【01】理解库,获取节点,连缀,
封装常用的js(Base.js)——[01]理解库,获取节点,连缀, youjobit07 2014-10-10 15:32:59 前言: 现如今有太多优秀的开源javascript库, ...
- 关于js with语句的一些理解
关于js with语句的一些理解 今天看到js的with语句部分,书中写到,with语句接收的对象会添加到作用域链的前端并在代码执行完之后移除.看到这里,我有两点疑问,添加到作用域链前端是不是指对 ...
- JS高阶函数的理解(函数作为参数传递)
JS高阶函数的理解 高阶函数是指至少满足下列条件之一的函数. · 函数可以作为参数被传递 · 函数可以作为返回值输出 一个例子,我们想在页面中创建100个div节点,这是一种写法.我们发现并不是所有用 ...
- 使用 js 实现十大排序算法: 插入排序
使用 js 实现十大排序算法: 插入排序 插入排序 // 双重循环 refs xgqfrms 2012-2020 www.cnblogs.com 发布文章使用:只允许注册用户才可以访问!
- 图说js中的this——深入理解javascript中this指针
没搞错吧!js写了那么多年,this还是会搞错!没搞错,javascript就是回搞错! ………… 文章来源自——周陆军的个人网站:http://zhoulujun.cn/zhoulujun/html ...
- 《深入浅出Node.js》第6章 理解 Buffer
@by Ruth92(转载请注明出处) 第6章 理解 Buffer ✁ 为什么需要 Buffer? 在 Node 中,应用需要处理网络协议.操作数据库.处理图片.接收上传文件等,在网络流和文件的操作中 ...
- Node.js的process.nextTick(callback)理解
Node.js是单线程的,基于事件循环,非阻塞 IO的.事件循环中使用一个事件队列,在每个时间点上,系统只会处理一个事件,即使电脑有多个CPU核心,也无法同时并行的处理多个事件.因此,node.js适 ...
- Js 职责链模式 简单理解
js 职责链模式 的简单理解.大叔的代码太高深了,不好理解. function Handler(s) { this.successor = s || null; this.handle = funct ...
- JS魔法堂:彻底理解0.1 + 0.2 === 0.30000000000000004的背后
Brief 一天有个朋友问我“JS中计算0.7 * 180怎么会等于125.99999999998,坑也太多了吧!”那时我猜测是二进制表示数值时发生round-off error所导致,但并不清楚具体 ...
- js对于工厂模式的理解
有很多人对工厂模式有着这样或者那样不理解的地方,今天我就和大家分享一下我的心得. 其实工厂模式是基于面向对象的一种模式.大家先看这样的一段代码: 其实这个程序很简单,学过js的人都会写,基本没什么问题 ...
随机推荐
- java基础-流程控制-day04
目录 1. if单分支 2. if else 多分支 3. if else双分支 4. 随机生成一定区间的整数 5 switch语句 6. while循环 7. for循环 8. break cont ...
- 搬运 |(有刀🔪慎入)kwdnx、谷雨、更漏与我
本打算把文案投到官微,但官微说文案太长了,只能放删减版: 那就把文案放博客上吧 写于 癸卯年 戊午月 己亥日. 四年前的冬天我们初见,大家都是青涩的未成年人:在少年班团建的喧闹中,谷雨谈论高数竞赛,k ...
- Nginx Location 深入剖析及动静分离简易配置
本文为博主原创,未经允许不得转载: 1. location 使用分析 location 是 Nginx 配置 中的一个指令,用于访问的 URL 匹配,而在这个 location 中所配置的每个指令将会 ...
- java中native源码查找方法
以Object的hashCode()方法为例: 1. 下载openjdk源码或从github中查找,这里以github中查找为例:2. GitHub中查找https://github.com/bpup ...
- 【scikit-learn基础】--『回归模型评估』之误差分析
模型评估在统计学和机器学习中具有至关重要,它帮助我们主要目标是量化模型预测新数据的能力. 在这个数据充斥的时代,没有评估的模型就如同盲人摸象,可能带来误导和误判.模型评估不仅是一种方法,更是一种保障, ...
- P5707 【深基2.例12】上学迟到
1.题目介绍 2.题解 这里只有两个稍微注意的点 2.1 s % v != 0(向上取整) 这里的话,若是结果不为整数,我们必须向上取整,必须保证空余时间永远大于所需时间! 2.2 ceil向上取整函 ...
- 持续集成指南:Gitlab CI/CD 自动部署前端项目
前言 之前陆续写了 Gitlab 的安装使用还有 Gitlab CI/CD 的配置使用,已经把 AspNetCore 的后端项目都做了持续集成了,尝到甜头之后,现在前端的项目也要加入自动化部署,所以经 ...
- [转帖]离线部署单机kubenetes-1.28.4
系统版本: openEuler 22.03 (LTS-SP2) docker版本:24.0.7 kubenetes版本: 1.28.4 虚机IP: 192.168.177.138 基于 https:/ ...
- [转帖]Linux命令(51)——ipcs命令
https://cloud.tencent.com/developer/article/1380589 1.命令简介 ipcs命令用于报告Linux中进程间通信设施的状态,显示的信息包括消息列表.共享 ...
- [转帖]【TiDB】快速起步
1. 存储引擎的的功能 提供数据存储接口并持久化存储数据 2. LSM-tree 的特性 LSM-tree 结构本质上是一个用空间置换写入延迟,用顺序写入替换随机写入的数据结构 3. 数据库技术的发展 ...