对数组进行排序是JS中必备的知识点, 方法有很多种,学习过数据结构的知道,数组的排序方法也就很好理解。当然JS的数组排序也包括它自身的排序方式。
排序法一:sort()
var arr = [1,4,2,6,7,3,2];
arr.sort(function(a,b) {return a-b}); //升序 // arr.sort((a,b) => a - b)
arr.sort(function(a,b) {return b-a}); //降序 // arr.sort((a,b) => b - a)
// 执行解析
var arr = [1,4,2,6,7,3,2];
arr.sort(function(a,b) {
if(a > b) { // 若a > b 则交换位置
return 1; // 返回正数,b排在a之前
}else{ // 否则 位置不变 (包含相等)
return -1; // 返回负数,a排在b之前
}
})
arr.sort(function(a,b) {
return a-b
});
//升序
// 如果a大于b,那么数字中 a - b = 正数 => 返回值为正数 交换位置
// 如果a小于b,那么数字中 a - b = 负数 => 返回值为负数 不交换位置
排序法二: 选择排序法
var arr = [1,2,42,2,55,3,6,3]
for(var i = 0; i < arr.length; i++) {
for(var j = i+1; j < arr.length; j++) {
if(arr[i] > arr[j]) {
var temp = arr[i];
arr[i] = arr[j];
arr[j ] = temp;
}
}
}
console.log(arr);
排序法三:冒泡法
var arr = [1,2,42,2,55,3,6,3]
for(var i = 0; i < arr.length; i++) {
for(var j = 0; j < arr.length; j++) {
if(arr[j] > arr[j+1]) {
var temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
排序法四:桶排序
// 简单,但是不用,因为浪费内存
var arr2 = [];
for(var i = 0; i < arr.length; i++) {
var key = arr[i];
arr2[key] = 1;
}
console.log(arr2);
for(var j in arr2) {
console.log(j);
}
排序法五:标志性变量 + for
var arr = [1,2,34,1,4,1,2];
// 改进: 添加标志性变量pos
function Bubble_Sort2(arr) {
console.time('改进版冒泡排序');
var i = arr.length - 1;
var pos = 0; //初始时, 最后位置保持不变
for(var j = 0; j < i; i++) {
if(arr[j] > arr[j+1]) {
pos = j; //记录交换的位置
var temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
i = pos; //为下一趟排序作准备
}
console.timeEnd('改进版冒泡排序');
return arr;
}
console.log(Bubble_Sort2(arr));
希尔排序(性能最好的排序)
求max/min
法一:ES6方法
var arr = [1,2,3,6,3]
var max = Math.max(...arr); // 求最大值
var min = Math.min(...arr); // 求最小值
=== Math.max.apply(null, arr) //apply(null, arr) //可以使用apply将数组转为一个一个参数传入
方法二:for循环
var arr = [1,2,3,2,4]
var max = arr[0];
for(var i = 0; i < arr.length; i++) {
if(arr[i] > max) {
max = arr[i];
}
}
// 函数模型
function getMax(arr) {
if(!(Array.isArray(arr))) throw new Error('the param must be array');
var max = -Infinity; // 初始化max的值
for(var i = 0; i < arr.length; i++) {
if(arr[i] > max) {
max = arr[i];
}
}
return max;
}
// 原型上进行构造函数求最大值的方法, 可以将
if(!Array.prototype.max){
Array.prototype.max = function() {
var max = -Infinity, len = this.length;
for(var i = 0; i < len; i++) {
max = isNaN(this[i])? NaN : this[i] > max? this[i] : max
}
return +max //隐式转化为数字
}
}
// 优化:利用数组的内置方法进行优化 forEach,并利用Math.max进行求
if(!Array.prototype.max)) {
Array.prototype.max = function() {
var max = - Infinity;
this.forEach(function(item) {
max = Math.max(max, item);
})
return max;
}
}
// 优化: 利用数组的API reduce 方法 + Math.max
if(!Array.prototype.max){
Array.prototype.max = function() {
return this.reduce(function(a,b) {
return Math.max(a,b);
}, -Infinity)
}
}
// 优化: 不使用Math.max版本
if(!Array.prototype.max){
Array.prototype.max = function() {
return this.reduce(function(a,b) {
return (a > b)? a : b;
}, -Infinity)
}
}
// 优化: 利用eval() 函数 ???
Array.prototype.max = function() {
return eval("Math.max("+ this +")");
}
// 优化:利用apply() 函数
// call() 方法的作用和apply()方法类似,
// call() 方法接受的是若干个参数的列表,apply()方法接受的是一个包含多个参数的数组。
Array.prototype.max = function() {
return Math.max.apply(null, this);
}
根据结果发现,自己使用循环实现的方式是最快的,使用 Array.reduce 和 Math.max 的速度是最慢的