JavaScript 实现排序算法
参考文章:
1. 冒泡排序
思路
- 比较所有相邻元素,如果第一个比第二个大,则交换它们
- 一轮下来,可以保证最后一个数是最大的
- 执行n-1轮,就可以完成排序
代码
Array.prototype.bubbleSort = function () {
for (let i = 0; i < this.length - 1; i++) {
let hasSwapped = false // 本轮是否有交换行为
for (let j = 0; j < this.length - 1 - i; j++) {
if (this[j] > this[j + 1]) {
hasSwapped = true
const temp = this[j]
this[j] = this[j + 1]
this[j + 1] = temp
}
}
// 若本轮没有交换行为,则无需再进行下一轮遍历
if (!hasSwapped) {
break;
}
}
}
const arr = [5, 4, 3, 2, 1]
arr.bubbleSort()
console.log('arr', arr)
分析
- 时间复杂度:
- 最好:O(n)【已排好序的数组,没有交换,一轮遍历完成】
- 最坏:O(n2)
- 平均:O(n2)
- 空间复杂度:O(1)
- 排序方式:In-place
- 稳定性:稳定
2. 选择排序
思路
- 找到数组中的最小值(用indexMin来表示当前值下标,遍历遇到更小的就替换为它),将其放置在第一位(和原第一位交换)
- 接着找到第二小的值,选中它并将其放置在第二位
- 以此类推,执行n-1轮
代码
Array.prototype.selectionSort = function () {
for (let i = 0; i < this.length - 1; i++) {
let indexMin = i
for (let j = i; j < this.length; j++) {
if (this[j] < this[indexMin]) {
indexMin = j
}
}
// 若当前位就是最小位,则不交换
if (indexMin !== i) {
const temp = this[i]
this[i] = this[indexMin]
this[indexMin] = temp
}
}
}
const arr = [5, 4, 3, 2, 1]
arr.selectionSort()
console.log('arr', arr)
分析
- 时间复杂度:
- 最好:O(n2)
- 最坏:O(n2)
- 平均:O(n2)
- 空间复杂度:O(1)
- 排序方式:In-place
- 稳定性:不稳定
3. 插入排序
思路
- 将一个元素插入到前面排序的子序列中,使插入后的子序列仍然是排序的,n个元素共需n-1趟
- 从第二个数开始往前比,比他大就往后排,以此类推进行到最后一个数
代码
Array.prototype.insertionSort = function () {
for (let i = 1; i < this.length; i++) {
const num = this[i];
for (let j = i - 1; j >= 0; j--) {
if (num < this[j]) {
this[j + 1] = this[j]
}
else {
break
}
}
this[j + 1] = num
}
}
const arr = [5, 4, 3, 2, 1]
arr.insertionSort()
console.log('arr', arr)
分析
- 时间复杂度:
- 最好:O(n)
- 最坏:O(n2)
- 平均:O(n2)
- 空间复杂度:O(1)
- 排序方式:In-place
- 稳定性:稳定
4. 归并排序
思路
- 分:把数组劈成两半,再递归地对子数组进行“分”操作,直到分成一个个单独的数
- 合:把两个数合并为有序数组,再对有序数组进行合并,直到全部子数组合并为一个完整数组
- 合并两个有序数组
- 新建一个空数组res,用于存放最终排序后的数组
- 比较两个有序数组的头部,较小者出队并推入res中
- 如果两个数组还有值,就重复第二步
- 合并两个有序数组
代码
Array.prototype.mergeSort = function () {
// 终点
if (this.length === 1) {
return this
}
// 分
const mid = Math.floor(this.length / 2)
const left = this.slice(0, mid)
const right = this.slice(mid)
left.mergeSort()
right.mergeSort()
// 合
let res = []
while (left.length > 0 || right.length > 0) {
if (left.length > 0 && right.length > 0) {
left[0] < right[0] ? res.push(left.shift()) : res.push(right.shift())
}
else if (left.length > 0) {
res.push(left.shift())
} else {
res.push(right.shift())
}
}
// res 拷贝到 this
res.forEach((item, i) => {
this[i] = item
})
}
const arr = [5, 4, 3, 2, 1]
arr.mergeSort()
console.log('arr', arr)
分析
- 时间复杂度:
- 最好:O(nlogn)
- 最坏:O(nlogn)
- 平均:O(nlogn)
- 轮数:O(logn)
- 每轮遍历:O(n)
- 空间复杂度:O(n)
- 临时的数组 n + 递归时压入栈的数据占用的空间 logn
- 排序方式:Out-place
- 稳定性:稳定
5. 快速排序
思路
- 分区:在数据序列中选择一个元素作为基准值,每趟从数据序列的两端开始交替进行,将小于基准值的元素交换到序列前端,将大于基准值的元素交换到序列后端,介于两者之间的位置则成为基准值的最终位置(将基准值与最终位置或其前一位元素交换)。
- 递归:递归地对基准前后的子数组进行分区
代码
Array.prototype.quickSort = function () {
// end: 包括
const rec = (start, end) => {
if (end <= start) {
return
}
const pivot = this[start]
let i = start + 1
let j = end
while (i < j) {
while (this[i] <= pivot && i < j) {
i++
}
while (this[j] >= pivot && i < j) {
j--
}
// 若i<j,i和j交换
if (i < j) {
let temp = this[i]
this[i] = this[j]
this[j] = temp
}
}
// i == j 的情况
if (this[i] < pivot) {
// i和pivot交换
let temp = this[i]
this[i] = this[start]
this[start] = temp
rec(start, i - 1)
rec(i + 1, end)
} else {
// i-1和pivot交换
let temp = this[i - 1]
this[i - 1] = this[start]
this[start] = temp
rec(start, i - 2)
rec(i, end)
}
}
rec(0, this.length - 1)
}
const arr = [3, 1, 5, 4, 2]
arr.quickSort()
console.log('arr', arr)
分析
- 时间复杂度:
- 最好:O(nlog2n)
- 最坏:O(n2)【每轮选择的基准值都是极端值(最小/最大)】
- 平均:O(nlog2n)
- 轮数:O(log2n)
- 每轮遍历:O(n)
- 空间复杂度:O(logn)
- 递归时压入栈的数据占用的空间 logn
- 排序方式:In-place
- 稳定性:不稳定
JavaScript 实现排序算法的更多相关文章
- JavaScript版排序算法
JavaScript版排序算法:冒泡排序.快速排序.插入排序.希尔排序(小数据时,希尔排序会比快排快哦) //排序算法 window.onload = function(){ var array = ...
- javascript高级排序算法之快速排序(快排)
javascript高级排序算法之快速排序(快排)我们之前讨论了javascript基本排序算法 冒泡排序 选择排序 插入排序 简单复习: 冒泡排序: 比较相邻的两个元素,如果前一个比后一个大,则交换 ...
- javascript常用排序算法实现
毕业后,由于工作中很少需要自已去写一些排序,所以那些排序算法都忘得差不多了,不过排序是最基础的算法,还是不能落下啦,于是找了一些资料,然后用Javascript实现了一些常用的算法,具体代码如下: & ...
- javascript常用排序算法总结
算法是程序的灵魂.虽然在前端的开发环境中排序算法不是很经常用到,但常见的排序算法还是应该要掌握的.我在这里从网上整理了一下常见排序算法的javascript实现,方便以后查阅. 归并排序: 1 fun ...
- javascript的排序算法
已经准备秋招一段时间了,因为这个关系也在各种巩固知识,顺便整理一下一些东西.这篇文章就是自己整理了一下各种JS的排序算法,以便自己以后回顾. 冒泡排序 function bubbleSort(arr) ...
- JavaScript之排序算法
一.冒泡排序 原理:1.比较相邻的元素.如果第一个比第二个大,就交换两个数:2.对每一对相邻元素重复做步骤一,从开始第一对到结尾的最后一对,该步骤结束会产生一个最大的数:3.针对所有的数重复以上的步骤 ...
- JavaScript随机排序算法1
1.对数组循环,每一项与随机的某一项位置调换 <ul id="listOne"></ul> <div id="tempOne"&g ...
- JavaScript实现排序算法总结
<script type="text/javascript" src="js/laydate.js" > //插入排序 function inser ...
- javascript实现排序算法
准备好好学习js了,js写的第一个排序 先推荐一个js在线编辑工具,RunJS,还不错. 冒泡排序 var arr = [2,4,1,5,3]; function handle(arr){ for(v ...
随机推荐
- DataTable添加checkbox实现表格数据全选,单选(点选)
Datatables是一款jquery表格插件.它是一个高度灵活的工具,可以将任何HTML表格添加高级的交互功能. 分页,即时搜索和排序 几乎支持任何数据源:DOM, javascript, Ajax ...
- [.NET] WCFDataService项目host到IIS上碰到的一个问题:数据库未能打开
今天在尝试重现OP一个问题的,遇到了一个新的问题. 项目坏境: WCF Data Service 5.6 Entity Framewrok 5(不用6的原因时要重新配置WCF项目) SQL Serve ...
- editmd输出到前端显示
官方案例:html-preview-markdown-to-html.html 输出后台数据显示在前端,格式化内容<!DOCTYPE html> <html lang="z ...
- Spring Cloud Hystrix原理篇(十一)
一.Hystrix处理流程 Hystrix流程图如下: Hystrix整个工作流如下: 构造一个 HystrixCommand或HystrixObservableCommand对象,用于封装请求,并在 ...
- 第十一章节 BJROBOT PS3 手柄控制【ROS全开源阿克曼转向智能网联无人驾驶车】
1.把小车架空平放在地板上. 2.用 USB 线将 PS3 蓝牙手柄连接至小车主控端,初次连接手柄上的 4 个红色指示灯会同时闪烁; 3.按下手柄中间的圆形配对键,然后等待红灯闪烁至停止. 4.此 ...
- 使用docker制作Mysql镜像
一.过程说明 通过Dockerfile创建mysql镜像,使用的mysql软件包为mariadb二进制分发版,最终在宿主机启动mysql容器从而能在mysql容器外部访问mysql服务. 宿主机IP ...
- Hbase相关参数详解
转载:http://www.cnblogs.com/nexiyi/p/hbase_config_94.html 版本:0.94-cdh4.2.1 hbase-site.xml配置 hbase.tmp. ...
- shell脚本学习之6小时搞定(6)-重定向及其他
shell学习之-重定向及其他 目录 shell学习之-重定向及其他 1.输出重定向 2.输入重定向 3.重定向深入讲解 4./dev/null 文件 5.awk Unix 命令默认从标准输入设备(s ...
- try catch finally语句块中存在return语句时的执行情况剖析
2种场景 (1) try中有return,finally中没有return(注意会改变返回值的情形);(2) try中有return,finally中有return; 场景代码分析(idea亲测) 场 ...
- loj #6179. Pyh 的求和 莫比乌斯反演
题目描述 传送门 求 \(\sum\limits_{i=1}^n\sum\limits_{j=1}^m \varphi(ij)(mod\ 998244353)\) \(T\) 组询问 \(1 \leq ...