js数值排序中冒泡算法的4种简单实现
实现数组排序的算法很多,其中冒泡算法是比较简单的
冒泡的基本原理是相邻的两个数进行比较,按照排序的条件进行互换,例如对数值从小到大排序,
随着不断的互换,最大的那个值会慢慢冒泡到数组的末端
基于这个原理我们就可以写冒泡排序了
为了简单起见下面的例子都是对数值数组进行从小到大排序,先模拟一个20个字符的数组
function getRandomArr(n) {
let arr = [];
for (let i = 0; i < n; i++) {
arr.push(~~(Math.random() * 100));
}
return arr
}
let randomArr = getRandomArr(20);
第一种冒泡算法
从原理可知,冒泡算法最少是需要2层循环的,当其中一个数值冒泡到末端时,这个数值下次就不需要参与循环了,这样循环的范围就会慢慢缩小,最后数组完成排序
function bubbleSort(arr) {
let len = arr.length;
let temp;
let i = len - 1;
while(i > 0) {
for (let j = 0; j < i; j++) {
if (arr[j] > arr[j + 1]) {
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
i--;//不断缩小范围
}
return arr;
}
console.log(randomArr)//[ 93, 72, 29, 17, 82, 26, 56, 71, 35, 48, 37, 42, 3, 11, 33, 66, 81, 53, 59, 53 ]
console.log('bubbleSort', bubbleSort(randomArr.concat()));//bubbleSort [ 3, 11, 17, 26, 29, 33, 35, 37, 42, 48, 53, 53, 56, 59, 66, 71, 72, 81, 82, 93 ]
在冒泡的过程中,我们可以发现,如果数组后面部分已经排好序了,也就是不用再交换双方的位置时,只要记录好最后一次交换的位置,就有很大的可能缩小下次循环的范围,这样就能提高冒泡的性能(这只是猜想)
第二种冒泡算法
function bubbleSort2(arr) {
let len = arr.length;
let i = len - 1;
let temp;
let pos;//用来记录位置的
while (i > 0) {
pos = 0;//初始为0如果数组一开始已经排好序了,那么就可以很快终止冒泡
for (let j = 0; j < i; j++) {
if (arr[j] > arr[j + 1]) {
pos = j;
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
i = pos;
}
return arr;
}
console.log(randomArr)//[47, 31, 85, 65, 44, 56, 54, 5, 67, 44, 76, 13, 90, 12, 83, 72, 2, 69, 58, 60]
console.log('bubbleSort2', bubbleSort2(randomArr.concat()));//bubbleSort2 [2, 5, 12, 13, 31, 44, 44, 47, 54, 56, 58, 60, 65, 67, 69, 72, 76, 83, 85, 90]
其实对于第一种循环,是从左到右进行冒泡,我们也可以从右到左冒泡,但是从右到左的方法和第一种基本就一样了,但是我们可以在内层循环中实现先向左冒泡,再向右冒泡
第三种冒泡方法
function bubbleSort3(arr) {
let len = arr.length;
let low = 0;
let higth = len - 1;
let temp;
while (low < higth) {
for (let j = low; j < higth; j++) {
if (arr[j] > arr[j + 1]) {
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
higth--;
for (let j = higth; j > low; j--) {
if (arr[j] < arr[j - 1]) {
temp = arr[j];
arr[j] = arr[j - 1];
arr[j - 1] = temp;
}
}
low++;
}
return arr;
}
console.log(randomArr)//[40, 78, 16, 97, 38, 27, 66, 44, 45, 31, 12, 1, 99, 68, 36, 42, 40, 54, 6, 42]
console.log('bubbleSort3', bubbleSort3(randomArr.concat()));//bubbleSort3 [1, 6, 12, 16, 27, 31, 36, 38, 40, 40, 42, 42, 44, 45, 54, 66, 68, 78, 97, 99]
最后可以结合第三种和第二种方法
第四种冒泡的方法
function bubbleSort4(arr) {
let len = arr.length;
let low = 0;
let higth = len - 1;
let temp;
while (low < higth) {
let hPos = 0;
let lPos = higth;
for (let j = low; j < higth; j++) {
if (arr[j] > arr[j + 1]) {
hpos = j;
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
heigth = hPos;
for (let j = higth; j > low; j--) {
if (arr[j] < arr[j - 1]) {
lPos = j;
temp = arr[j];
arr[j] = arr[j - 1];
arr[j - 1] = temp;
}
}
low = lPos;
}
return arr;
}
console.log(randomArr)//[40, 78, 16, 97, 38, 27, 66, 44, 45, 31, 12, 1, 99, 68, 36, 42, 40, 54, 6, 42]
console.log('bubbleSort4', bubbleSort4(randomArr.concat()));//[1, 6, 12, 16, 27, 31, 36, 38, 40, 40, 42, 42, 44, 45, 54, 66, 68, 78, 97, 99]
下面对这4种方法在chrome控制台下进行一个简单的性能测试
var randomArr = getRandomArr(10000);
console.time('1');
bubbleSort(randomArr.concat());
console.timeEnd('1');
console.time('2');
bubbleSort2(randomArr.concat());
console.timeEnd('2');
console.time('3');
bubbleSort3(randomArr.concat());
console.timeEnd('3');
console.time('4');
bubbleSort4(randomArr.concat());
console.timeEnd('4');
VM371:4 1: 329.705ms
VM371:7 2: 379.501ms
VM371:10 3: 310.843ms
VM371:13 4: 306.847ms
在经过多次测试发现一个有趣的现象执行最快的是第4种方法,最慢的是第2种,没错最慢的是我认为可以提高性能的第2种方法,这就相当尴尬了,不知道有哪位小伙伴可以解释一下
js数值排序中冒泡算法的4种简单实现的更多相关文章
- JS去除数组中重复值的四种方法
JS去除数组中重复值的四种方法 1 /// <summary> o[this[i]] = ""; } } newArr.p ...
- JS基础入门篇( 三 )—使用JS获取页面中某个元素的4种方法以及之间的差别( 一 )
1.使用JS获取页面中某个元素的4种方法 1.通过id名获取元素 document.getElementById("id名"); 2.通过class名获取元素 document.g ...
- Js 在页面中输入消息的几种方式
一.方式 alert(“”); confirm(“”) ; prompt(“”); 接收用户信息 console.log(“”); 在网页控制台中输出消息 document. ...
- JS获取网页中HTML元素的几种方法分析
getElementById getElementsByName getElementsByTagName 大概介绍 getElementById ,getElementsByName ,getEle ...
- PHP 一致性哈希算法的一种简单实现
在分布式系统中,如果某业务可以由多个相同的节点处理,很容易想到用HASH的方式将业务请求分散到这些节点处理,比如memecache缓存等分 布式集群应用,如果只是简单的使用,不涉及用户用户状态等信息, ...
- canvas游戏和动画中的碰撞检测(2种简单方式)
碰撞检测关键步骤 碰撞检测需要处理经历下面两个关键的步骤: 计算判断两个物体是否发生碰撞 发生碰撞后,两个物体的状态和动画效果的处理 计算碰撞 只要两个物体相互接触,它们就会发生碰撞. 矩形物体碰撞检 ...
- iOS 开发中常用的排序(冒泡、选择、快速、插入、希尔、归并、基数)算法
1.冒泡排序: 冒泡算法是一种基础的排序算法,这种算法会重复的比较数组中相邻的两个元素.如果一个元素比另一个元素大(小),那么就交换这两个元素的位置.重复这一比较直至最后一个元素.这一比较会重复n-1 ...
- C语言——<算法>_冒泡算法的使用及理解
对数组内数值进行有规则排序时,就要用冒泡算法,也是比较简单的一个算法 #include <stdio.h> #include <stdlib.h> int main() { i ...
- (转)用JS实现表格中隔行显示不同颜色
用JS实现表格中隔行显示不同颜色 第一种: <style> tr{bgColor:expression( this.bgColor=((this.rowIndex)%2==0 )? ...
随机推荐
- 在性能测试时使用nmon进行监控服务器性能
在使用Jmeter进行性能测试,可以使用nmon进行服务器的监控. 一.nmon说明 nmon分为工具包和分析包(nmonanalyser) nmon安装很简单,根据服务器版本,下载相应的版本后,进行 ...
- Linux mysql ERROR 1045 解决
Linux mysql 5.6: ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES) ...
- Oracle 启用登录终端超时锁定功能
远程连接oracle 会出现超时连接断开的问题,所以需要修改oracle配置. 修改超时时间10分钟 ALTER PROFILE DEFAULT LIMIT IDLE_TIME 10; 查询修改后的超 ...
- HDU4372(第一类斯特林数)
题意:N座高楼,高度均不同且为1~N中的数,从前向后看能看到F个,从后向前看能看到B个,问有多少种可能的排列数. 0 < N, F, B <= 2000 首先我们知道一个结论:n的环排列的 ...
- k8s/01开启云原生之门(Mooc)
一.kubernetes(k8s)基础知识 1.简介 在2017年Kubernetes战胜了两个强大的竞争对手Swarm和Mesos,成为容器管理与调度编排领域的首选平台和事实标准. 2014年k8s ...
- mysql先分组,然后取每个分组中的第2大的记录
文章参考http://www.xaprb.com/blog/2006/12/07/how-to-select-the-firstleastmax-row-per-group-in-sql/ 首先建表: ...
- SVN的各种符号含义,svn的星号,感叹号,问号等含义
黄色感叹号(有冲突):--这是有冲突了,冲突就是说你对某个文件进行了修改,别人也对这个文件进行了修改,别人抢在你提交之前先提交了,这时你再提交就会被提示发生冲突,而不允许你提交,防止你的提交覆盖了别人 ...
- CentOS7 开启路由转发
1.临时开启,(写入内存,在内存中开启) echo "1" > /proc/sys/net/ipv4/ip_forward 2.永久开启,(写入内核) 在 vim /etc/ ...
- Android怎么改图标都不生效&&Android studio 如何修改APP图标和名字
去这里(我自己写的),解决方法包你满意: https://blog.csdn.net/qq_43141611/article/details/101875545
- Java内存结构详解
Java内存结构详解 Java把内存分成:栈内存,堆内存,方法区,本地方法区和寄存器等. 下面分别介绍栈内存,堆内存,方法区各自一些特性: 1.栈内存 (1)一些基本类型的变量和对象的引用变量都是在函 ...